文档对象模型DOM
文档对象模型 DOM(Document Object Module)是由 W3C 定义的提供与任何 HTML 或 XML 文档进行交互的 API(编程接口),可以说是 HTML 之后的又一伟大创新。它使得用户可以通过 javaScript 访问 HTML 文档中的任意元素和内容,DOM 提供的接口可以操作 HTML 文件中的节点。当浏览器加载一个网页后,这个网页就可以看作是文档树,由多个节点构成。所谓 DOM,就是将 HTML 文档中各个元素按照从属关系建立起的模型。总的来说,我们可以利用 DOM 完成以下应用:
- 访问指定节点;
- 访问相关节点;
- 访问节点属性;
- 检查节点类型;
- 创建节点;
- 为节点添加事件;
- 操作节点。
HTML 文档与 DOM
我们先看下面这个简单的 HTML 文档:
| |
这个 HTML 文档的 DOM 可示例如下图:

在上面的 DOM 中,html 位于最顶端,是 DOM 的根节点,head 和 body 是 html 的子节点,它们属于同一层,并不互相包含,是兄弟关系,h1 和 p 是兄弟元素,其父元素是 body,p 的子元素是 a 元素。
节点
节点(node)的概念来源于计算机网络,它代表网络中的一个连接点。在 DOM 中,文档也是由节点构成的集合。DOM 定义了多种节点,常用的是元素节点、文本节点、和属性节点,分别对应元素、元素中包含的文字内容和元素的属性。
例如上面的代码中:
| |
a 元素的 title 和 href 属性就是 a 元素节点的属性节点,a 元素所包含的内容“超级链接”就是文本节点。如下图所示:
| |
使用 DOM
DOM 提供了一种访问文档内容的机制,我们可以使用 DOM 处理 HTML 文档的内容。DOM 由节点(node)构成,每一个节点,都有一系列的属性、方法可以使用,常用属性、方法见下表:
| 属性/方法 | 类型/返回类型 | 说明 |
|---|---|---|
| nodeName | String | 节点名称 |
| nodeValue | String | 节点的值 |
| nodeType | Number | 节点类型 |
| firstChild | Node | childNodes 列表的第一个节点 |
| lastChild | Node | childNodes 列表的最后一个节点 |
| childNodes | NodeList | 所有子节点列表,方法 item(i) 可以访问其中节点 |
| parentNode | Node | 父节点 |
| previousSibling | Node | 指向前一个兄弟节点 |
| nextSibling | Node | 指向后一个兄弟节点 |
| hasChildNodes() | Boolean | 是否包含子节点 |
| attributes | NameNodeMap | 包含一个元素特性的 Attr 对象 |
| appendChild(node) | Node | 将 node 节点添加到 childNodes 末尾 |
| removeChild(node) | Node | 从 childNOdes 中删除 node 节点 |
| repaceChild(new,old) | Node | 将 childNodes 中的 oldnode 节点替换为 newnode 节点 |
| insertBefore(new,ref) | Node | 在 childNOdes 中的 refnode 节点之前插入 newnode 节点 |
| innerHTML | String | 读取或者设置某个标记之间的所有内容 |
| className | String | 读取或者设置节点的 CSS 类别 |
访问节点
DOM 提供了一些很便捷的方法来访问文档的节点,最常用的是 getElementsByTagName() 和getElementById(),此外比较常用的是 getElementsByName()、getElementsByClassName()、Document.querySelector()等等。
| |
将访问 oLi 子节点列表中的第一个节点的值。
检测节点类型
通过节点的 nodeType 属性可以检测出节点的类型,DOM 定义了 12 种类型,大多数情况下,我们用到的是以下类型:
ELEMENT_NODE元素节点 nodeType 的值为 1;ATTRIBUTE_NODE属性节点 nodeType 的值为 2;TEXT_NODE文本节点 nodeType 的值为 3;
利用父子兄关系查找节点
在获取了某个节点之后,可以通过父子关系,利用 hasChildNodes() 方法和 childNodes 属性获取该节点所包含的所有子节点。例如:
| |
从运行结果我们可以看出,不光有元素节点,连它们之间的空格也被当成了子节点。
通过 parentNode 属性,可以获取父元素节点。如:
| |
DOM 还提供了处理兄弟之间关系的属性和方法,如 nextSibling、previousSibling。
设置节点属性
找到节点后,可以通过 getAttribute()、setAttribute() 方法取得或者设定节点的属性。
| |
创建和添加节点
创建元素节点采用 creatElment(), 创建文本节点采用 creatTextNode(), 创建文档碎片节点采用 creatDocumentFragment() 等等。
在插入元素之前,先将元素内容添加到元素节点,再将元素节点及其包含的文本节点添加到指定节点。
| |
删除节点
删除节点使用 removeChild() 方法,通常先找到要删除的节点,然后利用 parentNode 属性找到父节点,然后使用父节点的 removeChild 方法。
| |
替换节点
DOM 提供 replaceChild() 方法来替换节点,具体过程和删除节点类似,先找到想要替换的节点,再创建新节点,然后使用父节点替换方法。
| |
innerHTML 属性
innerHTML 属性虽然不是 W3C DOM 的组成部分,但它得到了目前主流浏览器的支持。该属性表示某个标记之间的所有内容,包括代码本身。
| |
className 属性
className 属性是一个非常实用的属性,可以修改一个节点的 CSS 类别。
| |
使用 className 属性如果要追加 CSS 样式,而不是覆盖 CSS 样式的话,使用“+=”连接运算符,另外注意不同的样式名称使用空格分割。