DOM结构深度优先遍历(一):NodeIterator

NodeIterator和TreeWalker能够基于给定的起点对DOM结构进行深度优先(depth-first)的遍历操作。

IE不支持DOM遍历。

可以使用下面代码检测浏览器DOM2级遍历能力的支持:

var supportTraversala = document.implementation.hasFeature("Traversal","2.0");
var supportNodeIterator = (typeof document.createNodeIterator == "function");
var supportTreeWalker = (typeof document.createTreeWalker == "function");

 

NodeIterator基本介绍:

可以使用document.createNodeIterator()创建NodeIterator类型的新实例,语法如下:

document.createNodeIterator(root, whatToShow, filter, EntityReferenceExpansion)


参数说明:
root:想要作为搜索起点的树中的节点;
whatToShow:表示要访问哪些节点的数字代码;
filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数;可以不指定即为null;
EntityReferenceExpansion:布尔值,表示是否扩展实体应用。这个参数在HTML中没有用,因为其中的实体引用不能扩展。

其中,whatToShow是一个位掩码,这个参数的值以常量形式在NodeFilter类型中定义,下面是常用的几个值:

NodeFilter.SHOW_ALL:显示所有类型 的节点
NodeFilter.SHOW_ELEMENT:显示元素节点
NodeFilter.SHOW_TEXT:显示文本节点
NodeFilter.SHOW_COMMENT:显示注释节点
NodeFilter.SHOW_DOCUMENT:显示文档节点

NodeIterator的创建:

下面举个demo栗子:

HTML结构如下:

<div id="root">
  <p>hello</p>
<div> 
<p>world</p>
<ul>
  <li>
    <p>html</p>
  </li>
</ul>
</div>
</div>

 

每个NodeFilter对象只有一个方法,那就是acceptNode();

如果要访问给定的节点,该方法返回NodeFilter.FILTER_ACCEPT;

如果要跳过访问给定的节点,该方法返回NodeFilter.FILTER_REJECT或者NodeFilter.FILTER_SKIP

使用对象方式创建一个filter过滤器:

var filter = {
acceptNode:function(node){
return node.tagName.toLowerCase() == 'p' ?
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_SKIP; //或者NodeFilter.FILTER_REJECT
}
}

var root = document.getElementById('root');

var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);

 

或者使用匿名函数方式,创建一个filter过滤器

var filter = function(node){
return node.tagName.toLowerCase() == 'p' ?
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_REJECT; //或者NodeFilter.FILTER_SKIP
}

var root = document.getElementById('root');

var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);

 

上面两种方式,就可以创建一个NodeIterator节点迭代器,当然了,如果不指定过滤器filter,也可以传入null,比如:

var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);


这样生成的NodeIterator就可以访问所有节点。

NodeIterator的主要方法应用:

NodeIterator的主要方法是nextNode()和previousNode()。

在深度优先的DOM子树遍历中,nextNode()用于向前前进一步,previousNode()用于向后后退一步。

在遍历到DOM子树的最后一个节点时,nextNode()返回null;在previousNode()返回根节点之后,再次调用previousNode()也会返回null。

下面是demo实例:

HTML结构:

<div id="root">
  <p>hello</p>
  <div> 
    <p>world</p>
    <ul>
      <li>
        <p>html</p>
      </li>
    </ul>
  </div>
</div>

 

如果想遍历root下所有元素,可以这样做:

var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, null, false);

var node = iterator.nextNode();

while(node !== null){
console.log( node.tagName );
node = iterator.nextNode();
}


结果输出:DIV P DIV P UL LI P(这里做一行展示,实际在浏览器中是分行打印的)

如果想遍历root下所有的p元素,可以这样做:

var filter = function(node){
return node.tagName.toLowerCase() == 'p' ?
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_REJECT;
}


var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);

var node = iterator.nextNode();

while(node !== null){
console.log( node.tagName );
node = iterator.nextNode();
}

 

结果输出:P P P(这里做一行展示,实际在浏览器中是分行打印的)
————————————————
版权声明:本文为CSDN博主「TianyuCool」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35087256/article/details/80920081

喜欢这篇文章?欢迎打赏~~

 

posted @ 2020-03-13 11:03  苍青浪  阅读(581)  评论(0编辑  收藏  举报