• 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

  • 相关阅读:
    sql server 复制数据库
    sql server 修改数据库名、修改逻辑文件名、修改数据库物理文件名
    前端工具集合
    如何写一个日历组件
    封装一个通过class获取元素的方法--我的JS原生库(1)
    关于复选框选中状态的判断
    42种常见的浏览器兼容性问题大汇总(转载)
    CSS样式命名整理(非原创)
    setTimeout和setInterval实现滚动轮播中,清除定时器的思考
    注册登陆拖拽验证(1)
  • 原文地址:https://www.cnblogs.com/cangqinglang/p/12485085.html
Copyright © 2020-2023  润新知