treewalker 是 javascript dom 遍历接口,需通过 document.createtreewalker() 创建;其核心参数为根节点、位掩码 whattoshow(如 nodefilter.show_element)、可选 filter 对象(含 acceptnode 方法返回 filter_accept/reject/skip),调用 nextnode() 等方法实现游标式遍历。

TreeWalker 不是 HTML 语法,而是 JavaScript 提供的 DOM 遍历接口;直接在 HTML 文件里写 TreeWalker 不会生效,必须通过 document.createTreeWalker() 在 JS 中创建并使用。
怎么用 document.createTreeWalker() 创建遍历器
核心是调用该方法,传入根节点、过滤类型、可选的 NodeFilter 对象(控制是否跳过某节点):
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
{
acceptNode(node) {
// 只保留 class="active" 的元素,或非空文本节点
if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('active')) {
return NodeFilter.FILTER_ACCEPT;
}
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
}
);
-
document.body是起始遍历根节点,可以换成任意Element或Document - 第二个参数是位掩码,常用组合:
NodeFilter.SHOW_ELEMENT、NodeFilter.SHOW_TEXT、NodeFilter.SHOW_COMMENT - 第三个参数可省略(此时默认接受所有匹配类型的节点),但一旦提供,就必须是带
acceptNode方法的对象 - 注意:
acceptNode返回值必须是NodeFilter.FILTER_ACCEPT/FILTER_REJECT/FILTER_SKIP三者之一,不能返回布尔值
walker.nextNode() 和 walker.firstChild() 的行为差异
TreeWalker 是「游标式」遍历器,所有移动方法都改变内部指针位置,并返回当前节点(或 null):
-
walker.nextNode():跳到「文档顺序」中下一个符合条件的节点(深度优先,从左到右) -
walker.previousNode():反向回到上一个符合条件的节点 -
walker.firstChild():只进入当前节点的**第一个子节点**(如果存在且被接受),不跨层级跳转 -
walker.parentNode():向上回到父节点(前提是父节点本身也满足过滤条件) - 容易踩坑:多次调用
nextNode()不会自动重置;若想重新遍历,需手动把walker.currentNode设为根节点,再调用firstChild()或nextNode()
为什么不用 querySelectorAll 而要用 TreeWalker
当需要动态、流式、带状态的遍历逻辑时,TreeWalker 更灵活:
-
querySelectorAll返回静态NodeList,无法跳过中间节点、无法按自定义规则「边走边判」 -
TreeWalker支持在acceptNode中访问父/兄弟上下文,比如「只取某个容器内、且前面紧邻<h2></h2>的<p></p>」——这种关系型判断很难用 CSS 选择器表达 - 性能上,
TreeWalker是惰性遍历,不预先收集全部节点;对超大 DOM(如含数千个节点的编辑器内容)更友好 - 兼容性没问题:Chrome 1+、Firefox 2+、Safari 3+、Edge 全支持,无需 polyfill
真正难的不是创建 TreeWalker,而是设计 acceptNode 的逻辑边界——比如要不要包含注释、是否允许跳过空文本、父节点不满足条件时子节点是否还能被接受。这些细节不写进过滤函数,遍历结果就可能和预期差很远。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











