DOM2定义了两个用于顺序遍历DOM结构的类型:NodeIteratorTreeWalker,这两个类型能够基于给定的起点对DOM结构执行深度优先的遍历操作。

NodeIterator

var nodeIterator = document.createNodeIterator(root, whatToShow, filter);
参数:

  • root: 遍历起点
  • whatToShow: 表示访问哪些节点的数字代码
  • filter: 是一个用来选择相关节点的NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数

方法:
parentNode()移动当前 Node到文档顺序中的第一个“可见”的祖先节点,并返回该节点。
firstChild()移动当前 Node到当前节点的第一个“可见”子节点,并返回该节点。

whatToShow 常用常量:

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

NodeFilter对象

NodeFilter 接口表示一个对象,此对象用于过滤 NodeIteratorTreeWalker 中的节点。它既不能处理 DOM,也不能遍历节点;它只能根据提供的过滤器对单个节点进行判定。
方法:NodeFilter.acceptNode()

常量 描述
FILTER_ACCEPT 当需要接受一个节点时,NodeFilter.acceptNode()返回该值。
FILTER_REJECT 当需要拒绝一个节点时,NodeFilter.acceptNode()返回该值。
对于 TreeWalker,这个节点的子节点也会被拒绝。
对于 NodeIterator,这个常量的表现与FILTER_SKIP一样。
FILTER_SKIP 当NodeIterator或 TreeWalker对象需要跳过一个节点时NodeFilter.acceptNode()返回该值。
但被跳过节点的子节点仍会被考虑,意即“跳过该节点但不包括其子节点”。

例:

  1. <div id="div1">
  2. <p>
  3. <b>Hello World</b>
  4. </p>
  5. <ul>
  6. <li>item 1</li>
  7. <li>item 2</li>
  8. <li>item 3</li>
  9. </ul>
  10. </div>
  1. var div = document.getElementById('#div1');
  2. var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, null);
  3. var node = iterator.nextNode();
  4. while(node !== null){
  5. console.log(node.tagName);
  6. node = iterator.nextNode();
  7. }
  8. // DIV
  9. // P
  10. // B
  11. // UL
  12. // LI
  13. // LI
  1. var div = document.getElementById('#div1');
  2. var filter = function(node){
  3. return node.tagName.toLowerCase() === 'li'
  4. ? NodeFilter.FILTER_ACCEPT
  5. : NodeFilter.FILTER_SKIP
  6. }
  7. var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, filter);
  8. var node = iterator.nextNode();
  9. while(node !== null){
  10. console.log(node.tagName);
  11. node = iterator.nextNode();
  12. }

兼容性

image.png

TreeWalker

TreeWalkerNodeIterator的一个更高级的版本。除了包括nextNode()previousNode()的方法之外,还提供了下列在不同方向上遍历DOM结构的方法:
parentNode()移动当前 Node到文档顺序中的第一个“可见”的祖先节点,并返回该节点。
firstChild()移动当前 Node到当前节点的第一个“可见”子节点,并返回该节点。
lastChild()移动当前 Node到当前节点的最末一个“可见”子节点,并返回该节点。
previousSibling()移动当前 Node到当前节点的前一个兄弟节点,并返回该节点。
nextSibling()移动当前 Node到当前节点的后一个兄弟节点,并返回该节点。
previousNode()移动当前 Node到文档顺序中前一个节点,并返回该节点。
nextNode()移动当前 Node到文档顺序中下一个节点,并返回该节点。

创建:
var walker = document.createTreeWalker(root, whatToShow, filter);

当我们知道

  • 元素在文档结构中的位置,利用TreeWalker即使不定义filter过滤器也能取得所有
  • 元素

    1. var div = document.getElementById('#div1');
    2. var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null);
    3. walker.firstChild(); // 转到<p>
    4. walker.nextSibling(); // 转到<ul>
    5. var node = walker.firstChild(); // 转到第一个<li>
    6. while(node !== null){
    7. console.log(node.tagName);
    8. node = walker.nextSibling();
    9. }

    兼容性

    image.png