12.3 遍历
“DOM2级遍历和范围”模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIterator和TreeWalker;
IE不支持DOM遍历;
NodeIterator
document.createNodeIterator()接收四个参数:
1.root:想要作为搜索起点的树中的节点;
2.whatToShow:表示要访问哪些节点的数字代码;
3.filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数;
4.entityReferenceExpansion:布尔值,表示是否要扩展实体引用;这个参数在HTML页面中没有用,因为其中的实体引用不能扩展;
whatToShow参数是一个位掩码,通过应用一或多个过滤器(filter)来确定要访问哪些节点;
这个参数的值以常量形式在NodeFilter类型中定义;
1.NodeFilter.SHOW_ALL:显示所有类型的节点;
2.NodeFilter.SHOW_ELEMENT:显示元素节点;
3.NodeFilter.SHOW_ATTRIBUTE:显示特性节点;由于DOM结构原因,实际上不能使用这个值;
4.NodeFilter.SHOW_TEXT:显示文本节点;
5.NodeFilter.SHOW_CDATA_SECTION:显示CDATA 节点;对HTML页面没有用;
6.NodeFilter.SHOW_ENTITY_REFERENCE:显示实体引用节点;对HTML页面没有用;
7.NodeFilter.SHOW_ENTITYE:显示实体节点;对HTML页面没有用;
8.NodeFilter.SHOW_PROCESSING_INSTRUCTION:显示处理指令节点;对HTML页面没有用;
9.NodeFilter.SHOW_COMMENT:显示注释节点;
10.NodeFilter.SHOW_DOCUMENT:显示文档节点;
11.NodeFilter.SHOW_DOCUMENT_TYPE:显示文档类型节点;
12.NodeFilter.SHOW_DOCUMENT_FRAGMENT:显示文档片段节点;对HTML页面没有用;
13.NodeFilter.SHOW_NOTATION:显示符号节点;对HTML页面没有用;
filter写法;
var filter = {
acceptNode: function (node) {
return node.tagName.toLowerCase() == "p" ?
NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_SKIP;
}
};
var filter = function (node) {
return node.tagName.toLowerCase() == "p" ?
NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_SKIP;
};
var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT,filter, false);
NodeIterator类型的两个主要方法是nextNode()和previousNode();
nextNode()方法用于向前前进一步,而previousNode()用于向后后退一步;
<div id="div1">
<p><b>Hello</b> world!</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>
var div = document.getElementById("div1");
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,
null, false);
var node = iterator.nextNode();
while (node !== null) {
alert(node.tagName); //输出标签名
node = iterator.nextNode();
}
DIV
P
B
UL
LI
LI
LI
TreeWalker
TreeWalker是NodeIterator的一个更高级的版本,也就是功能更多;
除了nextNode()和previousNode(),还有;
1.parentNode():遍历到当前节点的父节点;
2.firstChild():遍历到当前节点的第一个子节点;
3.lastChild():遍历到当前节点的最后一个子节点;
4.nextSibling():遍历到当前节点的下一个同辈节点;
5.previousSibling():遍历到当前节点的上一个同辈节点;
var div = document.getElementById("div1");
var filter = function (node) {
return node.tagName.toLowerCase() == "li" ?
NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_SKIP;
};
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT,filter, false);
var node = iterator.nextNode();
while (node !== null) {
alert(node.tagName); //输出标签名
node = iterator.nextNode();
}
filter可以返回的值有所不同;
NodeFilter.FILTER_ACCEPT,NodeFilter.FILTER_SKIP,NodeFilter.FILTER_REJECT;
在使用TreeWalker对象时,NodeFilter.FILTER_SKIP会跳过相应节点继续前进到子树中的下一个节点;
而NodeFilter.FILTER_REJECT则会跳过相应节点及该节点的整个子树;
TreeWalker真正强大的地方在于能够在DOM结构中沿任何方向移动;
var div = document.getElementById("div1");
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null, false);
walker.firstChild(); //转到<p>
walker.nextSibling(); //转到<ul>
var node = walker.firstChild(); //转到第一个<li>
while (node !== null) {
alert(node.tagName);
node = walker.nextSibling();
}
currentNode,表示任何遍历方法在上一次遍历中返回的节点;
var node = walker.nextNode();
alert(node === walker.currentNode); //true
walker.currentNode = document.body; //修改起点
可以修改遍历继续进行的起点;