JS 12.3 遍历

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; //修改起点

可以修改遍历继续进行的起点;