DOM 是 Document Object Model(文档对象模型)的缩写。DOM 描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。 HTML DOM 树形结构如下:
DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。节点分为几种不同的类型,每种类型分别表示文档中不同的信息及(或)标记。每个节点都拥有各自的特点、数据和方法,另外也与其他节点存在某种关系。
DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现。JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法。每个节点都有nodeType 、nodeName 和 nodeValue 属性。
nodeType属性:用于表明节点的类型。Node类型定义了12个常量值来表示不同节点类型,具体如下:
要了解节点的具体信息,可以使用 nodeName 和 nodeValue 这两个属性。这两个属性的值完全取决于节点的类型。例如:元素节点的 nodeName 是标签名称,属性节点的 nodeName 是属性名称;对于文本节点,nodeValue 属性包含文本。对于属性节点,nodeValue 属性包含属性值。nodeValue 属性对于文档节点和元素节点是不可用的。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>nodeType nodeName nodeValue属性title>
head>
<body>
<div id="div1">div内文本div>
body>
<script type="text/javascript">
var div = document.getElementById("div1");
console.log(div.nodeType); // 1
console.log(div.nodeName); // DIV
console.log(div.nodeValue); // null
var textNode = div.childNodes[0];
console.log(textNode.nodeType); //3
console.log(textNode.nodeName); //#text
console.log(textNode.nodeValue); //div内文本
script>
html>
上述代码创建了一个div元素节点,元素节点的nodeType为1,nodeName为对应的节点名称,nodeValue对元素节点不可用,因此为null。在div内还有一段文字,为文本节点,通过div.childNodes[0]可获得,文本节点的nodeType为3,nodeName永远是 #text,nodeValue 包含文本内容。
HTML文档可以描述成HTML DOM树,那么DOM树中的节点彼此拥有层级关系。父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。节点之间的关系可以表述如下:
与节点层次关系有关的属性
属性 | 含义 |
---|---|
parentNode | 获取该节点的父节点 |
childNodes | 获取该节点的子节点数组 |
firstChild | 获取该节点的第一个子节点 |
lastChild | 获取该节点的最后一个子节点 |
nextSibling | 获取该节点的下一个兄弟节点 |
previousSibling | 获取该节点的上一个兄弟节点 |
为了解释上述属性的具体含义,下面通过具体代码实现。首先建立HTML文档如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM树节点层次关系title>
head>
<body>
<div id="father">
<p id="child1">child1p>
<p id="child2">child2p>
<p id="child3">child3p>
div>
body>
html>
1、parentNode
var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");
console.log(child1.parentNode.nodeName); //DIV
console.log(child1.parentNode===child2.parentNode); // true
获取id为child1的p元素的parentNode为DIV,child2和child1的parentNode为同一个。
2、childNodes
var nodelist = father.childNodes;
console.log(nodelist.item(1).innerHTML); // child1
console.log(nodelist[1].innerHTML); // child1
console.log(nodelist.length); // 7
上述代码获取div的childNodes,其中保存着一个 NodeList 对象。 NodeList 是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。上述代码第二行和第三行描述了如何获取里面的节点,可以通过方括号,也可以使用 item()方法。并且可以通过.length
来获取 NodeList 对象中有几个节点。
我们注意到div中只有三个P元素,为何通过.length
得到的结果是7呢?这是因为我们在写HTML文档时存在换行空格,这些换行空格表示一个文本节点,我们可以通过for循环来遍历NodeList 对象中的每一个节点:
for (var i = 0; i < nodelist.length; i++) {
// console.log(nodelist[i].nodeType);
if (nodelist[i].nodeType==1) {
console.log(nodelist[i].innerHTML);
}else{
console.log(nodelist[i].nodeType+":"+nodelist[i].nodeName+":("+nodelist[i].nodeValue+")");
}
}
在FireFox浏览器中得到的结果如下:
3、firstChild
firstChild即获取某个节点的第一个子节点,要获取第一个子节点也可以通过someNode.childNodes[0]或someNode.childNodes.item(0)获取。
4、lastChild
lastChild即获取某个节点的最后一个子节点,要获取最后一个子节点也可以通过someNode.childNodes [someNode.childNodes.length-1]或者someNode.childNodes.item(someNode.childNodes.length-1)
5、nextSibling
nextSibling即获取该节点的下一个兄弟节点,同一兄弟级节点中最后一个节点的 nextSibling 属性的值为 null:
console.log(nodelist[0].nextSibling); //
console.log(child1.nextSibling); //
console.log(nodelist[nodelist.length-1].nextSibling); // null
6、previousSibling
previousSibling即获取该节点的上一个兄弟节点,同一兄弟级节点中最后一个节点的 previousSibling属性的值同样为null:
console.log(nodelist[0].previousSibling); // null
console.log(child1.previousSibling); //
console.log(nodelist[nodelist.length-1].previousSibling); //
另外, hasChildNodes()也是一个非常有用的方法,这个方法在节点包含一或多个子节点的情况下返回 true;当然,也可以通过childNodes的length 属性来判断是否存在子节点。
元素节点
但是大部分情况下,我们都是需要对元素节点进行操作,对应的元素节点的属性的如下:
属性 | 含义 |
---|---|
children | 所有子元素节点 |
childElementCount | 子元素节点个数量 |
firstElementChild | 第一个子元素节点 |
lastElementChild | 最后一个子元素节点 |
nextElementSibling | 下一个兄弟元素节点 |
previousElementSibling | 前一个兄弟元素节点 |
上述的六个属性只包含元素节点,不包含文本节点,因此可以避免我们在程序中出现的换行空格被当做文本节点的情况,以下还是以上述的DOM结构来测试这六个元素节点属性。
var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");
var childrenlist = father.children;
console.log(childrenlist.length); // 3
console.log(father.childElementCount); // 3
console.log(childrenlist[1]); // "child2">
console.log(father.firstElementChild); //
"child1">
console.log(father.lastElementChild); //
"child3">
console.log(child1.nextElementSibling); //
"child2">
console.log(child1.previousElementSibling); // null
console.log(child3.nextElementSibling); // null
console.log(child3.previousElementSibling); //
"child2">