DOM节点遍历

Posted zhanglw456

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DOM节点遍历相关的知识,希望对你有一定的参考价值。

"DOM2级遍历和范围"模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIterator 和 TreeWalker 。这两个类型能够根据给定的节点对DOM结构进行深度优先(depth-first)遍历操作。

浏览器支持:Firefox、Safari、Opera、Chrome、IE9+。

1、NodeIterator

使用 document.createNodeIterator(root, whatToShow, filter, entityReferenceExpansion),创建 NodeIterator 实例。

  1)root:搜索起始节点

  2)whatToshow:表示要访问那些节点,有下列值,

          NodeFilter.SHOW_ALL:所有节点

          NodeFilter.SHOW_ELEMENT:元素节点

          NodeFilter.SHOW_ATTRIBUTE:特性节点,实际不能使用改值

          NodeFilter.SHOW_TEXT:文本节点

          NodeFilter.SHOW_CDATA_SECTION:CDATA 节点,对html页面没有用

          NodeFilter.SHOW_ENTITY_REFERENCE:实体应用节点,对HTML页面没有用

          NodeFilter.SHOW_ENTITY:实体节点,对HTML页面没有用

          NodeFilter.SHOW_PROCESSING_INSTRUCTION:处理指令节点,对HTML页面没有用

          NodeFilter.SHOW_COMMENT:注释节点

          NodeFilter.SHOW_DOCUMENT:文档节点

          NodeFilter.SHOW_DOCUMENT_TYPE:文档类型节点

          NodeFilter.SHOW_FRAGMENT:文档片段节点,对HTML页面没有用

          NodeFilter.SHOW_NOTATION:符号节点,对HTML页面没有用

          除了 NodeFilter.SHOW_ALL外,可以使用按位或操作来组合多个选项,如 var whatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT.

  3)filter:一个NodeFilter对象,或者是一个表示接受或拒绝的函数。NodeFilter 对象只有一个方法,acceptNode(),定义可访问的情况,返回 NodeFilter.FILTER_ACCEPT 或 NodeFilter.FILTER_SKIP(跳过当前节点)。并且 NodeFilter 是一个抽象类型,不能直接创建它的实例,可以创建一个包含acceptNode() 

方法,直接传入 document.createNodeIterator() 中。如果不指定过滤器,传入 null 即可。

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

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

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

以上 filter 和 filter1 都表示只访问 <p>元素。

  4)entityReferenceExpansion

       布尔值,表示是否要扩展实体应用,在HTML页面中没有用

 

NodeIterator 主要有两个方法:

    1)nextNode(),迭代器内部指针往下移动一位,并返回下一个遍历的节点。一开始迭代器内部指针指向根节点,所以第一次遍历调用返回根节点,当遍历到最后一个节点时返回 null

    2)previousNode(),迭代器内部指针往上移动一位,并返回上一个遍历的节点,第一次遍历调用返回根节点

2、TreeWalker

使用document.createTreeWalker()创建实例,接受四个参数,与document.createNodeIterator()相同。

1)TreeWalker 包含了 NodeIterator 所有功能,还提供了几个新方法,用于移动遍历位置:

      patentNode():跳转到当前节点的父节点

      firstChild():跳转到当前节点的第一个字节点

      lastChild():跳转到当前节点的最后一个节点

      nextSibling():跳转到当前节点的后一个同胞节点

      previousSibling():跳转到当前节点的前后一个同胞节点

      currentNode():当前迭代器内部指针所指向的节点,可以设置,改变继续遍历迭代的起点

2)filter 返回值除了 NodeFilter.FILTER_ACCEPT 或 NodeFilter.FILTER_SKIP,还可以是 NodeFilter.FILTER_REJECT(跳过当前节点及该节点的整个子树)。

3、示例

<table id="filesTable">
                <colgroup>
                    <col style="width: 25%" />
                    <col style="width: 35%" />
                    <col style="width: 15%" />
                    <col style="width: 25%" />
                </colgroup>
                <thead>
                <tr>
                    <th>Date</th>
                    <th>File name</th>
                    <th>File size</th>
                    <th>Operation</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td>Date</td>
                    <td>File name</td>
                    <td>File size</td>
                    <td><button class="button-list downloadBtn" data="">Download</button></td>
                </tr>
                <tr>
                    <td colspan="4">No data</td>
                </tr>
                </tbody>
            </table>

 var table = document.getElementById("filesTable");
 var iterator = document.createNodeIterator(table,NodeFilter.SHOW_ELEMENT,null,false);
 var node = iterator.nextNode();  // 返回table,迭代器内部指针往下移
 var node1 = iterator.previousNode();  // table,造成迭代器中table迭代两次
 while(node != null){
     console.log(node.tagName); // (2)TABLE、COLGROUP、(4)COL、THEAD、TR、(4)TH、TBODY、TR、(4)TD、BUTTON、TR、TD
     node = iterator.nextNode();
 }

  var walker = document.createTreeWalker(table,NodeFilter.SHOW_ELEMENT,null,false);
  walker.firstChild();  // 转到<colgroup>
  walker.nextSibling();  // 转到 <thead>
  node = walker.firstChild(); // 转到 <thead>中的<tr>
 while(node != null){
     console.log(node.tagName); // TR、(4)TH、TBODY、TR、(4)TD、BUTTON、TR、TD
     node = walker.nextNode();
 }

 

以上是关于DOM节点遍历的主要内容,如果未能解决你的问题,请参考以下文章

PHP DOM 遍历 HTML 节点和子节点

遍历DOM树时Jsoup节点哈希码冲突

遍历 NodeList 时移除 DOM 节点

JS遍历DOM 节点树的实现

JavaScript 将片段附加到DOM而不是每个节点。

Android之DOM解析XML