createNodeIterator 是 DOM 提供的轻量可控节点遍历工具,按深度优先前序遍历,通过 whatToShow 位掩码和自定义 filter 精准筛选节点,支持 nextNode/previousNode 步进式双向游走。

createNodeIterator 是 DOM 提供的专门用于按需遍历节点的工具,它比递归遍历或 querySelectorAll 更轻量、更可控——不一次性收集所有节点,而是“走一步算一步”,配合过滤器(whatToShow 和 filter)精准停在你关心的节点上。
明确 whatToShow:决定哪些类型节点可被访问
这是最基础的过滤开关。它是一个位掩码值,用常量组合控制“允许进入迭代器视野”的节点类型。常用值有:
-
NodeFilter.SHOW_ELEMENT:只进元素节点(如<div>、<p>) -
NodeFilter.SHOW_TEXT:只进文本节点(含空格、换行等) -
NodeFilter.SHOW_COMMENT:进注释节点 - 可组合使用,例如:
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
注意:即使节点类型符合,仍可能被后续 filter 函数进一步拦截。
自定义 filter 函数:实现业务逻辑级过滤
传入 createNodeIterator 的第四个参数是一个对象,其 acceptNode 方法返回 NodeFilter.FILTER_ACCEPT、FILTER_REJECT 或 FILTER_SKIP。这是真正写判断逻辑的地方:
立即学习“Java免费学习笔记(深入)”;
-
FILTER_ACCEPT:当前节点被接纳,nextNode()会返回它 -
FILTER_REJECT:跳过该节点,且不进入其子树(相当于剪枝) -
FILTER_SKIP:跳过该节点,但继续遍历它的子节点
例如,只接受 class 含 "active" 的元素节点:
const filter = {
acceptNode(node) {
return node.nodeType === Node.ELEMENT_NODE &&
node.classList.contains('active')
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT;
}
};
步进式遍历:用 nextNode() 和 previousNode() 控制节奏
创建后不自动执行,完全由你调用方法驱动:
-
iterator.nextNode():移动到下一个匹配节点,返回该节点;无更多时返回null -
iterator.previousNode():回退到上一个匹配节点(支持双向游走) -
iterator.currentNode:始终指向当前定位的节点(初始为根节点,非过滤后首个)
典型用法是 while 循环,避免死循环的关键是检查返回值是否为 null:
const iter = document.createNodeIterator(
root,
NodeFilter.SHOW_ELEMENT,
filter
);
let node;
while ((node = iter.nextNode()) !== null) {
console.log(node); // 每次只处理一个符合条件的节点
}
实用技巧:结合 root 节点与深度优先顺序理解行为
createNodeIterator 默认按**深度优先、前序遍历**(根→左→右)方式扫描整个子树。起始 root 节点本身也会参与过滤和判断。若只想遍历后代(不含 root),可先用 iter.nextNode() 跳过它。另外,filter 中可通过 node.parentNode 或 node.parentElement 获取上下文,实现“父元素满足某条件才接受子节点”这类嵌套逻辑。


















