《JS高程(3)》DOM2和DOM3-遍历-第12章笔记(24)

本文介绍了DOM2级遍历和范围模块中的NodeIterator和TreeWalker两种类型,这两种类型能基于给定的起点对DOM结构执行深度优先遍历。文章详细解释了如何使用这些API遍历DOM树,包括创建实例、指定过滤条件及遍历方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

IE不支持DOM遍历,使用以下代码检测浏览器对DOM2级遍历能力的支持的情况:

var supportsTraversals = document.implementation.hasFeature("Traversal", "2.0");

var supportsNodeIterator = (typeof document.createNodeIterator == "function");

var supportsTreeWalker = (typeof document.createTreeWalker == "function");

DOM结构执行深度优先,说明移动方向至少有两个。遍历一给定节点为根,不可能向上超出DOM树的根节点。

以HTML页面为例:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Example</title>
    </head>
    <body>
        <p><b>Hello</b>World</p>
    </body>
</html>

DOM树:
这里写图片描述
以document为根节点的DOM树进行深度优先遍历的先后顺序。
这里写图片描述

NodeIterator

NodeIterator类型,可以使用document.createNodeIterator()方法创建新的实例,接受4个参数:

参数
root:想要作为搜索起点的树中的节点
whatToShow:表示要访问哪些节点的数字代码
filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数
entityRefrenceExpansion:布尔值,表示是否要扩展实体引用。在HTML页面中没用,因为其中的实体引用不能扩展。

whatToShow参数是一个位掩码,通过应用一个或多个过滤器(filter)来确定访问哪些节点。这个参数的值以常量形式在NodeFilter类型中定义:

NodeFilter.SHOW_ALL:所有类型节点;

NodeFilter.SHOW_ELEMENT:元素;

NodeFilter.SHOW_ATTRIBUTE:特性;

NodeFilter.SHOW_TEXT:文本;

NodeFilter.SHOW_COMMENT;

NodeFilter.SHOW_DOCUMENT;

NodeFilter.SHOW_DOCUMENT_TYPE;

filter

可以使用createNodeIterator()方法的filter参数来指定自定义的NodeFilter对象,每个NodeFilter对象只有一个方法,应该访问的节点返回NodeFilter.FILTER_ ACCEPT;不应该访问的节点返回NodeFilter.FILTER_SKIP

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

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

第三个函数也可以是一个与acceptNode()方法类似的函数:

var filter = function (){
    return node.tagName.toLowerCase() == "p"?
    NodeFilter.FILTER_ACCEPT:
    NodeFilter.FILTER_SKIP;
};
var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);

如果不指定过滤器,在第三个参数出传入null。

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

nextNode()方法用于向前前进一步,第一调用时会返回根节点,遍历到最后一个节点时,返回null;

previousNode()方法用于后退一步,遍历到最后一个节点时,返回根节点,再次调用返回null。

以下面HTML为例:

<div id="div1">
    <p><b>Hello</b>world!</p>
    <ul>
        <li>List item1</li>
        <li>List item2</li>
        <li>List item3</li>
    </ul>
</div>

遍历所有<div>元素:

var div = document.getElementById("div1");
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, null, false);
var node = iterator.nextNode();
while(node !== null){
    // DIV P B UL LI LI LI LI
    alert(node.tagName);
    node = iterator.nextNode();
}

只返回<li>元素:

var div = document.getElementById("div1");
var filter = function(node){
    return node.tagName.toLowerCaxe() == "li"?
    NodeFilter.FILTER_ACCEPT:
    NodeFilter.FILTER_ACCEPT;
};

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

var node = iterator.nextNode();
while(node !== null){
    alert(node.tagName);
    node = iterator.nextNode();
};
TreeWalker

TreeWalker是NodeIterator的一个更高级的版本,除了nextNode()和previousNode()在内的相同的功能之外,还提供了其他遍历DOM结构的方法。

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

创建 TreeWalker对象方法:document.createTreeWalker();

参数:4个;

var div = document.getElementById("div1");
var filter = function(node){
    return node.tagName.toLowerCase() == "li";?
    NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
}

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

var node = walker .nextNode();
while (node !== null){
    alert(node.tagName);
    node = walker .nextNode();
}

TreeWalker真正强大的地方在于能够在DOM结构中沿任何方向移动,即使不使用过滤器也可以得到想要的元素:

var div = document.getElementById("div1");
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null, false);

walker.firstChild();
walker.nextSibling();

var node = walker.firstChild();
while (node !== null){
    alert(node.tagName);
    node = walker.nextSilbling();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值