DOM结构深度优先遍历(二):TreeWalker

TreeWalker是NodeIterator的一个更高级的版本。

TreeWalker的创建

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

 

其中接收的参数与 document.createNodeIterator相同,作用也类似

举个栗子:

HTML结构:

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

 

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

var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, filter, false);

var node = walker.nextNode();

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

 

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

TreeWalker与NodeIterator中filter区别

在上一篇,使用NodeIterator对象时,NodeFilter.FILTER_SKIP和NodeFilter.FILTER_REJECT的作用是相同的:跳过指定的节点;但是,在使用TreeWalker对象时,NodeFilter.FILTER_SKIP会跳过相应的子节点继续前进到子树的下个节点,而NodeFilter.FILTER_REJECT则会跳过以及该节点的整个子树

可以把上面的demo改造一下,即把NodeFilter.FILTER_SKIP替换成NodeFilter.FILTER_REJECT:

 

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

 

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

var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, filter, false);

var node = walker.nextNode();

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

 

结果输出:P。

差别很明显,当指针遍历第一个P节点后,紧接着是DIV节点,而NodeFilter.FILTER_REJECT则会跳过DIV节点以及该节点的整个子树。

TreeWalker中更好的方法应用

除了nextNode()和previousNode(),TreeWalker还提供了更好用灵活的遍历DOM结构的方法:

parentNode():遍历到当前节点的父节点;
firstChild():遍历到当前节点的第一个子节点;
lastChild():遍历到当前节点的最后一个子节点;
nextSibling():遍历到当前节点的下一个同辈节点;
previousSibling():遍历到当前节点的上一个同辈节点;

根据上面的方法,即使不使用filter过滤器也能取得指定元素li

HTML结构

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

 

var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);

walker.lastChild(); //指针跳转到section

walker.lastChild(); //指针跳转到ul

var node = walker.firstChild(); //指针跳转到第一个li

while(node !== null){
console.log( node.tagName );
node = walker.nextSibling();
}

 

结果输出:LI LI LI

TreeWalker中的currentNode

currentNode属性表示任何遍历方法在上一次遍历中返回的节点:

var node = walker.nextNode(); 
node === walker.currentNode //true


currentNode属性还可以修改遍历的起点:

walker.currentNode = document.body
————————————————
版权声明:本文为CSDN博主「TianyuCool」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35087256/article/details/80920508

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

 

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