遍历DOM树所有子孙节点需从父节点出发递归或迭代访问后代元素、文本及注释节点;childNodes返回全部子节点(含文本、注释),children仅含元素节点;querySelectorAll('*')可一次性获取所有后代元素;TreeWalker支持按类型精细过滤遍历。

遍历 DOM 树的所有子孙节点,核心是**从某个父节点出发,递归或迭代访问其所有后代元素、文本节点、注释节点等**。默认情况下,childNodes 或 children 只返回直接子节点,要覆盖全部子孙,需深入每一层。
用递归方式遍历所有子孙节点(含文本、注释等)
这是最直观的方法,利用 node.childNodes 获取包括元素、文本、注释在内的所有子节点,再对每个子节点重复调用自身:
-
childNodes返回 NodeList,包含所有类型的子节点(Node.ELEMENT_NODE、Node.TEXT_NODE、Node.COMMENT_NODE等) - 递归前建议加类型判断,避免处理不需要的节点(比如空白文本节点)
- 示例代码:
function traverseAllNodes(node) {
// 处理当前节点(例如打印节点类型和内容)
console.log(node.nodeType, node.nodeName, node.nodeValue?.trim());
// 遍历每个子节点
for (let child of node.childNodes) {
traverseAllNodes(child);
}
}
// 从 body 开始遍历所有子孙
traverseAllNodes(document.body);
只遍历元素节点(忽略文本和注释)
如果只需要 <div>、<p> 这类标签元素,用 children(只含元素节点)配合递归更干净:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
children是 HTMLCollection,只包含Element类型子节点 - 适合大多数“操作 DOM 元素”的场景,避免误处理空格或换行产生的文本节点
- 示例:
function traverseElements(node) {
console.log('Element:', node.tagName);
for (let el of node.children) {
traverseElements(el);
}
}
traverseElements(document.getElementById('container'));
用 flat() + querySelectorAll 实现一次性获取所有子孙元素
如果不需要逐个访问过程,而是想拿到所有后代元素数组,可借助 CSS 选择器:
立即学习“Java免费学习笔记(深入)”;
-
element.querySelectorAll('*')返回该元素下所有后代元素(不含文本/注释) - 注意:
*匹配所有元素,但不包括伪元素;性能在深层嵌套时略低于原生遍历 - 支持链式操作,适合批量修改或筛选:
const container = document.getElementById('app');
const allDescendants = Array.from(container.querySelectorAll('*'));
allDescendants.forEach(el => {
if (el.classList.contains('highlight')) {
el.style.backgroundColor = 'yellow';
}
});
用 TreeWalker API 做灵活可控的遍历
这是标准且强大的方式,适合需要精细过滤(如跳过 script/style、只取文本节点等)的场景:
- 创建
TreeWalker对象,可设定节点类型过滤、是否跨进子树等 - 用
walker.nextNode()按文档顺序依次获取符合条件的节点 - 示例:只遍历所有元素节点(排除文本和注释)
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT, // 只显示元素节点
null,
false
);
let node;
while (node = walker.nextNode()) {
console.log('Element:', node.tagName);
}

















