素材巴巴 > 程序开发 >

遍历html结构下的整个节点,DOM遍历

程序开发 2023-09-04 08:43:50

前面的话

DOM遍历模块定义了用于辅助完成顺序遍历DOM结构的类型:Nodeiterator和TreeWalker,它们能够基于给定的起点对DOM结构执行深度优先(depth-first)的遍历操作。本文将详细介绍DOM遍历

[注意]IE8-浏览器不支持

定义

DOM遍历是深度优先的DOM结构遍历,遍历以给定节点为根,不可能向上超出DOM树的根节点。以下面的HTML页面为例

Example

Hello world!

下图展示了这个页面的DOM树

0818b9ca8b590ca3270a3433284dd417.png

任何节点都可以作为遍历的根节点,如果假设

元素为根节点,那么遍历的第一步就是访问

元素,然后再访问同为

元素后代的两个文本节点。不过,这次遍历永远不会到达、元素,也不会到达不属于元素子树的任何节点。而以document为根节点的遍历则可以访问到文档中的全部节点

下图展示了对以document为根节点的DOM树进行深度优先遍历的先后顺序

0818b9ca8b590ca3270a3433284dd417.png

从document开始依序向前,访问的第一个节点是document,访问的最后一个节点是包含"world!"的文本节点。从文档最后的文本节点开始,遍历可以反向移动到DOM树的顶端。此时,访问的第一个节点是包含"Hello"的文本节点,访问的最后一个节点是document节点。Nodeiterator和TreeWalker都以这种方式执行遍历

NodeIterator

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

root:想要作为搜索起点的树中的节点

whatToShow:表示要访问哪些节点的数字代码

filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数

entityReferenceExpansion:布尔值,表示是否要扩展实体引用。这个参数在HTML页面中没有用,因为其中的实体引用不能扩展

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

NodeFilter.SHOW_ALL:显示所有类型的节点

NodeFilter.SHOW_ELEMENT:显示元素节点

NodeFilter.SHOW_ATTRIBUTE:显示特性节点。由于DOM结构原因,实际上不能使用这个值

NodeFilter.SHOW_TEXT:显示文本节点

NodeFilter.SHOW_CDATA_SECTION:显示CDATA节点。对HTML页面没有用

NodeFilter.SHOW_ENTITY_REFERENCE:显示实体引用节点。对HTML页面没有用

NodeFilter.SHOW_ENTITYE:显示实体节点。对HTML页面没有用

NodeFilter.SH0W_PROCESSING_INSTRUCTION:显示处理指令节点。对HTML页面没有用

NodeFi1ter.SHOW_COMMENT:显示注释节点

NodeFilter.SHOW_DOCUMENT:显示文档节点

NodeFilter.SHOW_DOCUMENT_TYPE:显示文档类型节点

NodeFilter.SHOW_DOCUMENT_FRAGMENT:显示文档片段节点。对HTML页面没有用

NodeFilter.SHOW_NOTATION:显示符号节点。对HTML页面没有用

除了NodeFilter.SHOW_ALL之外,可以使用按位或操作符来组合多个选项,如下所示:

var whatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT;

可以通过createNodeIterator()方法的filter参数来指定自定义的NodeFilter对象,或者指定一个功能类似节点过滤器(node filter)的函数。每个NodeFilter对象只有一个方法,即acceptNode();如果应该访问给定的节点,该方法返回NodeFilter.FILTER_ACCEPT,如果不应该访问给定的节点,该方法返回NodeFilter.FILTER_SKIP。由于NodeFilter是一个抽象的类型,因此不能直接创建它的实例。在必要时,只要创建一个包含acceptNode()方法的对象,然后将这个对象传入createNodeIterator()中即可

下列代码展示了如何创建一个只显示

元素的节点迭代器

var filter = {

acceptNode:function(node){

return node.tagName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;

}

}

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

第三个参数也可以是一个与acceptNode()方法类似的函数,如下所示

var filter = function(node){

return node.tagName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;

}

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

一般来说,这就是在javascript中使用这个方法的形式,这种形式比较简单,而且也跟其他的javascript代码很相似。如果不指定过滤器,那么应该在第三个参数的位置上传入null

下面的代码创建了一个能够访问所有类型节点的简单的NodeIterator

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

NodeIterator类型的两个主要方法是nextNode()和previousNode()。顾名思义,在深度优先的DOM子树遍历中,nextNode()方法用于向前前进一步,而previousNode()用于向后后退一步

在刚刚创建的NodeIterator对象中,有一个内部指针指向根节点,因此第一次调用nextNode()会返回根节点。当遍历到DOM子树的最后一个节点时,nextNode()返回null。previousNode()方法的工作机制类似。当遍历到DOM子树的最后一个节点,且previousNode()返冋根节点之后,再次调用它就会返回null

以下面的HTML片段为例

Hello world!


标签:

上一篇: ruoyi(若依)框架 免登录设置 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。