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


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

两个小function实现XML和string相互转化知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。