介绍innerText, textContent, innerHTML的区别, 引起重排的几种情况, 以及几种常用的DOM方法.

innerText, textContent, innerHTML:

  1. textContent可以获取所有元素节点的文本内容, 包括<script><style>中的, 而IE专属属性innerText不会获取.
  2. innerText受样式影响, 不返回隐藏元素的文本, 而textContent会.
  3. 因为innerText受样式影响, 所以改变后会触发重排(reflow), 而textContent不会触发.
  4. innerHTML获取的是元素节点, 但很多人用innerHTML来获取或改变某个DOM元素的文本内容, 但实际上应该使用textContent, 这样就不会被解析为HTML, 对性能的影响较小, 还能避免XSS恶意程序的攻击.

重排

重排会重新安排页面的布局, 在一个元素节点中的重排指重新计算该元素的尺寸和位置, 并且会触发该元素子节点, 祖先元素的重排, 以及在出现在该元素之后的DOM元素的重排(下面有示例), 最后进行一次重绘(repaint). 重排是个很容易引起的现象, 但是对性能的影响很大, 在很多情况下相当于对整个页面的布局进行重新安排, 因此要尽量避免重排.

<重绘: 元素在页面中显示出来的样式发生改变, 就会引起重绘, 但此时元素的布局并未发生改变. 样式的改变的一些例子: 轮廓线(outline), 可见性(visibility), 背景颜色(background color).>

下列情况会引起重排:

  • 插入, 移除, 更新DOM中的元素
  • 改变页面内容, 如改变输入框中的文本
  • 移动DOM元素
  • 给DOM元素加动画效果
  • 计算元素的样式值, 如offsetHeight或getComputedStyle
  • 改变CSS样式
  • 改变元素的className
  • 添加或移除样式表
  • 改变视窗大小
  • 滚屏
1
2
3
4
5
6
7
8
9
10
11
<body>
<div class=”error”>
<h4>My Module</h4>
<p><strong>Error:</strong>Description of the error…</p>
<h5>Corrective action required:</h5>
<ol>
<li>Step one</li>
<li>Step two</li>
</ol>
</div>
</body>

在以上部分代码中, <p></p>的重排会引起子节点<strong></strong>, 祖先元素<div class=”error”></div>(和<body></body>[取决于浏览器]), 紧接其后的元素<h5></h5><ol></ol>的重排, 在Opera浏览器中, 大部分重排会引起页面的重新渲染.

几种常用DOM方法

appendChild

node.appendChild(newnode);

在父节点node下添加一个子节点newnode, 添加位置在原有子节点的末尾, 返回新添加的节点;

insertBefore

node.insertBefore(newnode, existingchild);

在父节点node下, 已存在的子节点existingchild前添加一个子节点newnode, 返回插入的节点;

将新建子节点置于父节点下首位:
(父节点下需至少含有一个子节点)

parent.insertBefore(new, parent.firstChild);

将新建子节点置于父节点下末尾:
(相当于appendChild)

parent.insertBefore(new, null);

nodeType

var type = node.nodeType;

节点类型, 用数字标识, 共有12种节点类型, 其中Element(元素)的nodeType为1, Attr(属性) = 2, Text(文本) = 3.

childNodes

var kids = node.childNodes;

获取父节点node的第一层所有类型的子节点集合, 返回的是NodeList, 并非数组, 如果要转化成数组需要用Array.from()或者...(spread operator).

children

var children = node.children;

获取父节点node下的所有第一层元素子节点.

firstChild

var child = node.firstChild;

获取父节点node的第一层第一个子节点, 若不存在则返回null.

firstElementChild

var element = node.firstElementChild;

获取父节点node的第一层第一个元素子节点.

lastElementChild

var element = node.lastElementChild;

获取父节点node的第一层最后一个元素子节点.

childElementCount

var count = node.childElementCount;

获取父节点node的第一层元素子节点个数, 相当于 node.children.length

removeChild

node.removeChild(oldnode);

从父节点node中移除某个子节点oldnode, 返回被移除的节点.

replaceChild

node.replaceChild(newchild, existingchild);

在父节点node下用newchild替换已存在子节点existingchild, 返回被移除的节点;

createElement

document.createElement([tagname]);

在document下创建元素;

createTextNode

document.createTextNode('some text');

在document下创建一个内容为’some text’的文字节点;

用法:

1
2
3
4
5
var element = document.createElement('h1');

element.appendChild(document.createTextNode('some text'));

// 结果: <h1>some text</h1>

参考