学习 TreeWalker api 并与普通遍历 DOM 方式进行比较

介绍 TreeWalker

TreeWalkerJavaScript 中用于遍历 DOM 树的一个接口。允许你以灵活的方式在 DOM 树中进行前向和后向遍历,包括访问父节点、子节点和兄弟节点。适用于处理复杂的 DOM 操作:在遍历过程中进行添加、删除或修改节点的操作,并继续遍历。

与普通的 for 循环 + querySelector 相比灵活性更高。执行速度方面,在 DOM 超过一定复杂度的情况下,TreeWalker 更快,后面会举例说明。

实践

创建 TreeWalker

可以使用 document.createTreeWalker 方法来创建一个 TreeWalker 对象。这个方法接受四个参数:

  • root:要遍历的根节点。
  • whatToShow(可选):一个整数,表示要显示的节点类型。默认值是NodeFilter.SHOW_ALL,表示显示所有节点。
  • filter(可选):一个 NodeFilter 对象,用于自定义过滤逻辑。
  • entityReferenceExpansion(可选):一个布尔值,表示是否展开实体引用。这个参数在现代浏览器中通常被忽略,因为实体引用在 HTML 中很少使用
const walker = document.createTreeWalker(
 document.body,//.root
 NodeFilter.SHOW_ELEMENT,// whatToShow(可选)
 null,// filter(可选)
 false //entityReferenceExpansion(可选)
)

NodeFilter.SHOW_ELEMENT 表示显示元素节点。

节点类型

NodeFilter 有 12 种节点类型,和 Node 接口的节点类型一一对应;

NodeFilterNode.prototype
SHOW_ELEMENT:显示元素节点。1: ELEMENT_NODE
SHOW_ATTRIBUTE:显示属性节点(在HTML 中不常用)。2: ATTRIBUTE_NODE
SHOW_TEXT:显示文本节点。3:TEXT_NODE
SHOW_CDATA_SECTION:显示CDATA 节点(在HTML 中不常用)。4:CDATA_SECTION_NODE
SHOW_ENTITY_REFERENCE:显示实体引用节点(在HTML 中不常用)。5: ENTITY_REFERENCE_NODE
SHOW_ENTITY:显示实体节点(在HTML 中不常用)。6 : ENTITY_NODE
SHOW_PROCESSING_INSTRUCTION:显示处理指令节点。7: PROCESSING_INSTRUCTION_NODE
SHOW_COMMENT:显示注释节点。8:COMMENT_NODE
SHOW_DOCUMENT:显示文档节点。9:DOCUMENT_NODE
SHOW_DOCUMENT_TYPE:显示文档类型节点。10: DOCUMENT_TYPE_NODE
SHOW_DOCUMENT_FRAGMENT:显示文档片段节点。11 : DOCUMENT_FRAGMENT_NODE
SHOW_NOTATION:显示符号节点(在HTML 中不常用)。12 : NOTATION_NDE

NodeFilter.SHOW_ALL 表示显示所有类型节点,这和遍历节点的 childNodes 一样,childNodes 会把该节点下的所有类型的子节点遍历出来。而节点的 children 就只遍历元素节点。

自定义过滤器

可以通过传递一个 NodeFilter 对象来实现自定义的过滤逻辑。NodeFilter 对象有一个 acceptNode 方法,该方法返回一个常量来决定是否接受节点:

  • NodeFilter.FILTER_ACCEPT:接受节点。
  • NodeFilter.FILTER_REJECT:拒绝节点及其子节点。
  • NodeFilter.FILTER_SKIP:跳过节点,但继续遍历其子节点。
const filter = {
 acceptNode: function (node){
 if (node.tagName=== "DIV"){
 return NodeFilter.FILTER_ACCEPT;
 }else {
 return NodeFilter.FILTER_SKIP;
 }
 },
};
const walker = document.createTreeWalker(
 document.body,
 NodeFilter.SH