一、Dom的概念和节点层次
Dom:Document Object Model 文档对象模型,可以将任何 html 文档描绘成一个由多层次节点构成的结构。换而言之,就是Dom会把文档看成一棵树,同时定义很多方法来操作这棵树中的每一个元素(节点)。
文档:html 页面
文档对象:页面中的元素
文档对象模型:为了能够让程序(js)去操作页面中的元素
文档节点:文档节点是每个文档的根节点,文档节点只有一个子节点,即<html>元素,我们称为文档元素,文档元素是文档的最外层元素,文档中其他所有元素都包含在文档元素中,每个文档都只能有一个文档元素,在 html 页面中,文档元素始终是<html>元素。
二、Node类型
js中所有节点的类型都继承自 Node 类型。
共有12种类型,用12个数值来表示。
1.nodeType :返回节点的节点类型
我们只需要注意前三种即可,其他了解就好
元素节点 : 1
属性节点 : 2
文本节点 : 3
if(someNode.nodeType ==1){
alert(“Node is an element!”)
}
2.nodeName 和 nodeValue
nodeName :元素的标签名
nodeValue:始终为null
if(someNode.nodeType ==1){
value = someNode.nodeName //元素的标签名
}
在这个例子中,首先检查节点类型,看它是不是一个元素,如果是,则取得nodeName的值。
三、节点关系
1.childNodes 子节点列表集合,(只读属性)
每个节点都有一个 childNodes 属性,其中保存着一个NodeList对象(类数组对象),用来保存一组有序的节点,可以通过位置来访问这些节点。
注意:
1.是对象下的一种属性
2.使用时不加括号
3.只包含一级子节点,不包含后辈孙级以下的节点
4.标准下:包含了文本和元素类型的节点,也会包含非法嵌套的子节点
5.非标准下:只包含元素类型的节点,ie7以下不会包含非法嵌套子节点
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes[1];
//var secondChild = someNode.childNodes.item(1);
vat count = someNode.childNodes.length;
<script>
window.onload = function() {
var oUl = document.getElementById('ul1');
alert( oUl.childNodes.length );
//标准下为11,ie7以下为4(因为包括了文本节点和非法节点,ie7以下不识别)
}
</script>
<ul id="ul1" style="border: 1px solid red;">
<li>11111</li>
<li>22222</li>
<li>33333</li>
<li>44444</li>
<p>pppppppp</p>
</ul>
2.parentNode : 当前节点的父级节点(只读属性)
<script>
window.onload = function() {
var aA = document.getElementsByTagName('a');
for (var i=0; i<aA.length; i++) {
aA[i].onclick = function() {
this.parentNode.style.display = 'none';
//当点击标签a时,li隐藏
}
}
}
</script>
<body>
<ul id="ul1">
<li>11111 <a href="javascript:;">隐藏</a></li>
<li>22222 <a href="javascript:;">隐藏</a></li>
<li>33333 <a href="javascript:;">隐藏</a></li>
<li>44444 <a href="javascript:;">隐藏</a></li>
</ul>
</body>
3.previousSibling 和 nextSibling
注意:
1.可以访问同一列表的其他节点
2.列表中的第一个节点 previousSibling 属性值为null
3.列表中最后一个节点 nextSibling 属性值为null
4.如果列表中只有一个节点,那么该节点的 previousSibling 和 nextSibling 都为null
4.firstChild : 第一个子节点 (只读属性)
lastChild:最后一个节点 (只读属性)
注意:
1.标准下:firstChild 和lastChild会包含文本类型的节点
2.非标准下:只包含元素节点
3.在只有一个节点的情况下,firstChild 和lastChild 指向同一个节点
4.如果没有子节点,firstChild 和lastChild 均为null
var oUl = document.getElementById('ul1');
alert( oUl.firstChild ); //[object Text] 文本节点
<ul id="ul1">
<li>11111</li>
<li>22222</li>
<li>33333</li>
<li>44444</li>
</ul>
<script>
window.onload = function() {
var oUl = document.getElementById('ul1');
var oFirst = oUl.firstChild;
oFirst.style.background = 'red';
var oLast = oUl.lastChild;
oLast.style.background = 'yellow';
var oNext = oFirst.nextSibling;
oNext.style.background = 'blue';
var oPrev = oLast.previousSibling;
oPrev.style.background = 'orange';
//结果打开页面没有变化,因为他们的操作都会基于文本节点,文本节点没有style属性,所以不会有变化
}
</script>
<body>
<ul id="ul1">
<li>11111</li>
<li>22222</li>
<li>33333</li>
<li>44444</li>
</ul>
</body>
解析:打开页面没有变化,因为他们的操作都会基于文本节点,文本节点没有style属性,所以不会有变化
5.hasChildNodes()
在节点包含一个或多个子节点的情况下返回true,比查询childNodes列表的length更简便
6.ownerDocument 指向表示整个文档的文档节点
表示任何节点都属于它所在的文档,任何节点都不能同时存在于两个或者更多个文档中,这个属性,可以直接访问文档节点
四、基本节点操作方法
1.appendChild(要添加的元素) [方法] 追加子元素
用于在ChildNodes列表的末尾添加一个节点,添加节点后,ChildNodes 的新增节点,父节点以及以前的最后一个节点的关系指针都会相应的得到更新。
var oUl = document.getElementById('ul1');
var oLi = document.createElement('li');
<body>
<input type="text" id="text1" /><input type="button" value="留言" id="btn" />
<ul id="ul1"></ul>
</body>
结果如下图:
2.insertBefore(新的元素,被插入的元素) [方法]
将节点放在某个特定的位置
<script>
window.onload = function() {
var oUl = document.getElementById('ul1');
var oLi = document.createElement('li');
oUl.insertBefore( oLi, oUl.children[0] );
}
</script>
<body>
<ul id="ul1">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
结果如图所示
3.replaceChild(要插入的节点,被替换节点) 替换子节点 [方法]
要替换的节点将这个方法返回并从文档树中删除,同时由要插入的节点占据其位置
<script>
window.onload = function() {
var oDiv = document.getElementById('div1');
var oBtn = document.getElementById('btn');
var oP = document.getElementById('p1');
oBtn.onclick = function() {
document.body.replaceChild( oDiv, oP );
//当点击按钮后,p标签被div标签替换
}
}
</script>
<body>
<div id="div1">div1</div>
<input type="button" value="按钮" id="btn" />
<hr />
<p id="p1">ppppp</p>
</body>
removeChild(要删除的元素); 删除元素 [方法]
被移除的节点称为该方法的返回值
<script>
window.onload = function() {
var oUl = document.getElementById('ul1');
var oLi = document.getElementsByTagName('li')[0];
var child = oUl.removeChild( oLi);
}
</script>
<body>
<ul id="ul1">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
结果如图:
五、其他操作方法
1.cloneNode()用于创建调用这个方法的节点的一个完全相同的副本 [方法]
该方法接收一个布尔值参数,表示是否执行深复制
参数为true,执行深复制,即复制节点及整个子节点树
参数为false,执行浅复制,即只复制该节点本身
<script>
window.onload = function() {
var oUl = document.getElementById('ul1');
var deepList = oUl.cloneNode(true);
alert(deepList.childNodes.length); //7
var shallowList = oUl.cloneNode(false);
alert(shallowList.childNodes.length); //0
}
</script>
<body>
<ul id="ul1">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
2.normalize(),处理文档树中的文本节点
当由于解析器的实现或Dom操作等原因,可能会出现文本节点不包括文本,或者接连出现两个文本节点的情况,当在某个节点上调用该方法时,就会在该节点的后代节点上查找上述两种情况,如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。