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
喜欢这篇文章?欢迎打赏~~