DOM遍历

“DOM2级遍历和范围”模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIteratorTreeWalker。这两个类型能够基于给定的起点对DOM结构执行深度优先遍历。
DOM遍历是深度优先的DOM结构遍历,也就是说,移动的方向至少有两个。遍历以给定的节点为根,不可能向上超出DOM树的根节点。下面我们通过一个例子来了解一下:
这里写图片描述
任何节点都可以作为遍历的根节点。假设我们现在要以body元素作为根节点,那么遍历的第一步就是访问p元素,然后在访问同为body元素后代的两个文本节点。不过,这次遍历永远不会到达html,head元素。

简单了解之后,我们现在来了解遍历的两种方法。

NodeIterator

我们可以使用document.creatNodeIterator()方法来创建它的新实例。这个方法接受四个参数:

  • root:想要做为搜索起点的树中的节点。
  • whatToShow:表示要访问哪些节点的数字代码。
  • filter:表示应该接受还是拒绝某种特定节点的函数。
  • entrtyReferenceExpansion:布尔值,表示是否要扩展实体引用。

我们可以通过creatNodeIterator()方法的filter参数来指定自定义的NodeFilter对象,或者指定一个功能类似节点过滤器的函数。每个NodeFilter对象只有一个方法,即acceptNode();如果应该访问给定的节点,该方法返回NodeFilter.FITER_ACCEPT,如果不应该访问,则返回 NodeFilter.FITER_SKIP或者NodeFilter.FITER_REJECT。下面我们通过一个例子来简单了解一下,这段代码展示了如何创建一个只显示p元素的节点迭代器。

var fiter = function(node){
        return node.tagName.toLowerCase() === 'p'?
        NodeFilter.FITER_ACCEPT: NodeFilter.FITER_SKIP
};
var iterator = document.creatNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);

如果不指定过滤器,那么应该在第三个参数的位置传入null。通过下面的代码我们就可以访问所有类型节点。

var iterator = document.creatNodeIterator(root,NodeFilter.SHOW_ALL,null,false);

NodeIterator类型的两个主要方法是nextNode()和previousNode()。

  • nextNode():用于向前前进一步。第一次调用nextNode()会返回根节点。当遍历到最后一个节点时,nextNode()返回null。
  • previousNode():用于向后后退一步。当遍历到最后一个节点,且previousNode()返回根节点之后,再次调用就返回null。

    下面我们就通过一下例子来演示一下:


<div id="div1">
    <p><b>Mr.</b></p>
    <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
    </ul>
</div>

如果现在我们想遍历li元素,我们就可以像这样:

var oDiv = document.getElementById('div1');
var filter = function (node) {
        return node.tagName.toLowerCase() === 'li' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    };
var iterator = document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,filter,false);
var node  = iterator.nextNode();
while (node !== null){
       console.log(node.tagName.toLowerCase());
       node = iterator.nextNode();
   }

TreeWalker

TreeWalker是NodeIterator的一个更高级的版本。除了nextNode()和previousNode()方法外,这个类型还提供了下列的方法:

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

    创建TreeWalker对象使用document.creatTreeWalker()方法,这个方法接受的四个参数和document.creatNodeIterator()方法相同。
    下面来看一下使用该方法来实现上面的例子:

var oDiv = document.getElementById('div1');
var filter = function (node) {
        return node.tagName.toLowerCase() === 'li' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    };
var iterator = document.createTreeWalker(oDiv,NodeFilter.SHOW_ELEMENT,filter,false);
var node  = iterator.nextNode();
while (node !== null){
       console.log(node.tagName.toLowerCase());
       node = iterator.nextNode();
   }

在这里,filter可以返回的值不同。除了NodeFilter.FILTER_ACCEPT :和NodeFilter.FILTER_SKIP,还可以使用NodeFilter.FILTER_REJECT。在使用NodeIterator对象时,NodeFilter.FILTER_SKIP和NodeFilter.FILTER_REJECT的作用相同:跳过指定的节点。但在使用TreeWalker对象时,NodeFilter.FILTER_SKIP会跳过指定的节点继续前进到子树的下一个节点,但NodeFilter.FILTER_REJECT会跳过相应节点及该节点的整个子树。例如前面的例子,如果我们将NodeFilter.FILTER_SKIP修改为NodeFilter.FILTER_REJECT,结果就是不会访问任何节点。因为第一个返回的节点是div,它的标签名不是li,于是就会返回NodeFilter.FILTER_REJECT,这样就会跳过整个子树。因为div是遍历的根节点,所以结果就会停止遍历。
当然,TreeWalker真正强大的地方在于能够在DOM结构中沿任何方向移动。这就需要使用到前面说到的它比NodeIterator多的方法了。具体的使用我就不一一说明了。

今天的学习分享就到这里啦,图书馆好热呀!买瓶饮料犒劳一下自己嘻嘻嘻~~
关于所写内容如果有什么问题和疑惑希望大家可以告诉我奥,我们大家一起进步~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值