[TOC]
# DOM
## DOM 的定义
DOM 是一种 API,其作用为在程序中使用 HTML 文档以及 XML 文档。在 DOM 中, HTML 文档与 XML 文档会以树形对象集合的形式被使用。这一树形结构称为 DOM 树。
DOM 树中的一个个对象被称为节点。节点之间形成了一个树形结构,树中的某个节点可能会引用另外一个节点。根据引用关系,分别有父节点、子节点、兄弟节点、祖先节点、子孙节点等类型。
### DOM Level 1
模块 | 说明
---|---
Core | 对包括 HTML 在内的基本 DOM 操作提供支持
HTML | 对一些专用于 HTML 文档的方法提供支持
方法名 | 说明
---|---
getElementsByTagName | 根据指定的标签名来获取元素
createElement | 创建新元素
appendChild | 插入元素
### DOM Level 2
模块 | 说明
---|---
Core | Level 1 Core 的扩展
HTML | Level 1 HTML 的扩展
Views | 对与文档显示状态相关的功能提供支持
Events | 对捕获、冒泡、取消等事件系统提供支持
Styles | 对与样式表相关的功能提供支持
Traversal and Range | 对 DOM 树的遍历以及范围的指定提供支持
### DOM Level 3
模块 | 说明
---|---
Core | Level 2 Core 的扩展
Load and Save | 对文档内容的读取与写入提供支持
Validation | 对文档内容合法性的验证提供支持
XPath | 对 XPath 相关的功能提供支持
Events | Level 2 Events 的扩展。对键盘事件提供了支持
## 元素、节点
元素和节点之间略有一些继承关系,其中节点是父类概念。节点具有 nodeType 这一属性,如果其值为 ELEMENT_NODE(1),该节点则是一个元素。
节点 | 节点类型常量 | 节点类型的值 | 接口
---|---|---|---
元素节点 | ELEMENT_NODE | 1 | Element
属性节点 | ATTRIBUTE_NODE | 2 | Attr
文本节点 | TEXT_NODE | 3 | Text
注释节点 | COMMENT_NODE | 8 | Comment
文档节点 | DOCUMENT_NODE | 9 | Document
## Live 对象的特征
类似 `getELementsByTagName()` 方法获取到的对象是一个 NodeList 对象,是一个 Live 对象。
Live 对象始终具有 DOM 树实体的引用。对 DOM 树做出的变更也会在 Live 对象中得到体现。
## 父节点、子节点、兄弟节点
属性名 | 能够获取的节点
---|---
parentNode | 父节点
childNode | 子节点列表
firstChild | 第一个子节点
lastChild | 最后一个子节点
nextSibling | 下一个兄弟节点
previousSibling | 上一个兄弟节点
此外,空白符也会作为文本节点处理。
还制定了一套用于获取一些不包含空白节点与注释节点的元素的API
属性名 | 能够获取的节点
---|---
chidlren | 子元素节点列表
firstElementChild | 第一个子节点
lastElementChild | 最后一个子节点
nextElementSibling | 下一个兄弟节点
previousElementSibling | 上一个兄弟节点
childElementCount | 子元素的数量
## Selector API
`querySelector()` 将只会返回第一个与条件相符的元素。
`querySelectorAll()` 将返回所有符合条件的元素。取得的是一个 StaticNodeList 对象。
StaticNodeList 对象和 NodeList 对象不同点在于,对 StaticNodeList 对象进行修改则不会反应在 HTML 文档中。
## 节点的内容更改
通过 `replaceChild()` 方法替换节点
```javascript
parentNode.replaceChild(newNode, oldNode);
```
## textContent
`textContent` 属性可以取得包含子元素在内的纯文本部分。
```javascript
element.textContext = '<div> div here </div>'; // 不会创建 div 元素。在浏览器中将会直接显示该字符串
```
## DOM 操作的性能
如果在显示上发生了变化,浏览器则要重新绘制画面。画面的重新绘制这一步骤是需要花费开销的,所以要尽可能避免重新绘制画面。
使用 `DocumentFragment` 可将画面的重绘次数降至 1 次。
```javascript
var fragment = document.createDocumentFragment();
for(var i=0; i < 10; i++){
var child = document.createElement('div');
fragment.appendChild(child);
}
document.body.appendChild(fragement);
```