1. 引言DOMDocument Object Model文档对象模型是浏览器将 HTML 文档解析后生成的一棵节点树它把页面中的每一个元素、文本、属性都抽象为节点并通过树形结构组织起来。理解 DOM 节点树是掌握 JavaScript 操作页面、实现动态交互的基础。本文将从节点树的构成、节点类型、遍历方式到实战案例带你系统掌握 DOM 节点树的核心知识。2. 什么是 DOM 节点树当浏览器加载一个 HTML 页面时会按照文档的层级结构把每个标签、文本、注释等解析为一个节点并按照父子、兄弟关系组织成一棵倒置的树。树的顶端是document节点往下依次是html、head、body等元素节点。以下面这段 HTML 为例!DOCTYPE html html head title示例页面/title /head body h1欢迎访问/h1 p这是一段strong加粗/strong的文本/p /body /html它对应的节点树结构如下flowchart TD A[document] -- B[html] B -- C[head] B -- D[body] C -- E[title] D -- F[h1] D -- G[p] G -- H[文本: 这是一段] G -- I[strong] G -- J[文本: 的文本] I -- K[文本: 加粗]可以看到每个节点都有明确的父子关系html是head和body的父节点而head和body互为兄弟节点。3. 节点类型DOM 规范定义了多种节点类型日常开发中最常用的是元素节点、文本节点和注释节点。我们可以通过nodeType属性来判断节点的类型。节点类型nodeType 值说明元素节点1对应 HTML 标签如div、p属性节点2标签上的属性如id、class文本节点3标签内的文本内容注释节点8HTML 注释!-- --文档节点9整个文档的根节点document下面通过一段代码来验证节点类型// 获取 body 下的第一个子节点 const body document.body; const firstChild body.firstChild; console.log(body.nodeType); // 1元素节点 console.log(firstChild.nodeType); // 可能是 3文本节点或 1元素节点 // 遍历 body 的所有子节点并输出类型 for (let i 0; i body.childNodes.length; i) { const node body.childNodes[i]; console.log(节点名称: ${node.nodeName}, 类型: ${node.nodeType}); }需要注意的是childNodes会包含文本节点包括空白和换行而children只包含元素节点这是两者最直观的区别。4. 节点树的核心属性要熟练操作节点树需要掌握节点之间的导航属性。这些属性帮助我们从一个节点出发找到它的父节点、子节点和兄弟节点。4.1 父子关系// 获取父节点 const parent element.parentNode; // 获取子节点列表包含文本节点 const allChildren element.childNodes; // 获取子元素列表只包含元素节点 const elementChildren element.children; // 获取第一个和最后一个子节点 const first element.firstChild; const last element.lastChild;4.2 兄弟关系// 获取上一个和下一个兄弟节点 const prev element.previousSibling; const next element.nextSibling; // 只获取元素类型的兄弟节点 const prevElement element.previousElementSibling; const nextElement element.nextElementSibling;这里有一个常见的坑previousSibling和nextSibling会把换行和空格当作文本节点返回而previousElementSibling和nextElementSibling则只返回元素节点推荐优先使用后者。5. 遍历节点树在实际开发中我们经常需要遍历整棵节点树。除了使用递归现代浏览器还提供了NodeIterator和TreeWalker两种遍历器。5.1 使用 TreeWalker// 创建一个 TreeWalker只遍历元素节点 const walker document.createTreeWalker( document.body, NodeFilter.SHOW_ELEMENT ); let node walker.nextNode(); while (node) { console.log(node.tagName); node walker.nextNode(); }5.2 使用 NodeIterator// 创建 NodeIterator遍历所有节点 const iterator document.createNodeIterator( document.body, NodeFilter.SHOW_TEXT ); let textNode iterator.nextNode(); while (textNode) { console.log(文本内容: ${textNode.textContent}); textNode iterator.nextNode(); }相比手动递归这两种方式更安全因为它们会正确处理节点的新增和删除不会出现死循环。6. 实战动态构建节点树理解了节点树的结构后我们通过一个完整的案例来巩固知识。下面的代码演示了如何动态创建一棵节点树并把它插入到页面中。// 创建一个卡片容器 const card document.createElement(div); card.className card; // 创建标题 const title document.createElement(h2); title.textContent 动态节点树; // 创建内容段落 const content document.createElement(p); content.textContent 这段内容是通过 JavaScript 动态创建的。; // 创建列表 const list document.createElement(ul); const items [节点创建, 节点插入, 节点删除]; items.forEach(text { const li document.createElement(li); li.textContent text; list.appendChild(li); }); // 组装节点树 card.appendChild(title); card.appendChild(content); card.appendChild(list); // 插入到页面中 document.body.appendChild(card);运行这段代码后页面上会出现一张卡片包含标题、段落和列表。整个过程展示了createElement、appendChild等核心 API 的用法。7. 实战节点树的删除与替换除了创建节点删除和替换也是高频操作。下面演示如何安全地移除和替换节点。// 获取要删除的节点 const oldNode document.getElementById(old-content); // 方式一通过父节点删除 oldNode.parentNode.removeChild(oldNode); // 方式二直接删除现代浏览器支持 oldNode.remove(); // 替换节点 const newParagraph document.createElement(p); newParagraph.textContent 这是替换后的内容; oldNode.parentNode.replaceChild(newParagraph, oldNode);需要注意的是removeChild需要先获取父节点而remove()方法更简洁但兼容性稍差。在替换节点时replaceChild的第一个参数是新节点第二个参数是被替换的旧节点顺序不要写反。8. 总结DOM 节点树是前端开发的核心概念之一。本文从节点树的定义出发介绍了节点类型、导航属性、遍历方式并通过实战案例演示了节点的创建、插入、删除和替换。掌握这些知识后你就能更加灵活地操作页面结构实现复杂的动态交互效果。建议读者在浏览器控制台中亲自运行本文的代码示例加深对节点树的理解。