返回 ELI5 知识库首页 🌳 BROWSER INTERNALS & WEB ARCHITECTURE
🌳 DOM · Document Object Model · The Living Lego Tree of the Web

什么是 DOM(文档对象模型 · 网页的乐高倒挂大树)?

从网络下载下来的 HTML 只是一段死气沉沉的纯文本字符字符串(就像一张印在纸上的建筑施工说明书);而 DOM(Document Object Model) 就是浏览器把它读进内存后“拼装成的一棵挂满活动机关的乐高倒挂大树(DOM 节点树)” —— 让 JavaScript 可以像长了手脚一样,随时精准抓住某个节点修改文字、换颜色、添加点击事件或拔掉重插

📄 原始 HTML:死板静态的纯文本字符

只是一堆字符串,程序无法动态操纵

当浏览器从服务器接收到 <html><body><h1>Hello</h1></body></html> 时,它只是一长串冰冷的文本。JavaScript 无法直接“跟字符串对话”,更无法知道点击的是哪个具体按钮。

<!DOCTYPE html> <html><body><button id="btn">Click</button></body></html> > 仅仅是一堆静止的 ASCII 字节流... ⚠️ 纯文本无生命 · 无法绑定事件 · 无法按对象交互
  • 静态无交互:只是排版格式,没有运行时的内存状态
  • 无法直接修改:修改文本必须整篇重新刷新下载
VS
🌳 DOM 树:内存中活生生的对象树状模型

每个标签都是对象,JS 随时随地精准操纵

浏览器 HTML 解析器逐行读取字符,在内存中实例化出 documentHTMLHeadingElementHTMLButtonElement 等活生生的 JavaScript 对象,父子兄弟节点紧密相连,赋予网页无限动态生命!

Document (根) <html> <head> (元数据) <body> (可见体) <h1> 标题 <button> (活机关) ✨ JavaScript 拥有完整的 CRUD 编程接口!
  • 随时响应事件:点击、滑动、键盘输入实时派发给节点
  • 动态增删改查:document.createElement() 随时拼装新结构
💡

一句话顿悟:DOM 的核心第一性原理

- 它是连接“静态标记语言(HTML)”与“动态编程语言(JavaScript)”的翻译桥梁与标准 API
- 浏览器把 HTML 字符解析为内存中的 DOM 树,再把 CSS 解析为 CSSOM 树,两者合并生成 Render Tree(渲染树),最后通过布局(Layout)与绘制(Paint)将绚丽的网页呈现在屏幕上!

拆解 DOM 体系的 4 大核心维度

从节点分类到事件流转,搞懂浏览器渲染引擎的核心机制

🧱

1. 节点的三大家族 (Node Types)

Element Node(元素节点): <div><p>Text Node(文本节点): 标签里的文字内容;Document Node: 整棵树的统领根节点。

🔍

2. 节点精准抓取与 CRUD

通过 document.querySelector('#btn') 秒级定位节点,调用 appendChild()remove()classList.add() 动态更新。

🌊

3. 事件冒泡与捕获机制

点击一个子按钮,事件会经历“从 Window 向下捕获(Capture) ➔ 到达目标(Target) ➔ 像气泡一样向上传递给父级(Bubble)”的完整生命周期。

4. 虚拟 DOM (Virtual DOM)

由于直接频繁操作真实 DOM 会触发昂贵的回流(Reflow)与重绘(Repaint),React/Vue 在内存中先用 JS 对象 Diff 比较,再批量更新真实 DOM!

🕹️ JavaScript 操纵 DOM 树沙盘演练台

观察 JavaScript 调用不同 DOM API 时,内存中的节点树与样式如何即时响应改变:

document.documentElement <html> (根容器)
document.body <body>
<h1 id="title"> "Hello World" ➔ "Hello ELI5!"
✏️ 动作 1:精准修改文本节点
const h1 = document.getElementById('title');
h1.innerText = 'Hello ELI5!';
浏览器定位到内存中的 H1 元素,更新其底层的 Text Node,触发页面局部重绘!
✔ DOM 属性修改完成 · 屏幕瞬间刷新显示
🌳 DOM 与 BOM 的区别

整个浏览器世界的全景版图

- DOM(Document Object Model): 专管 window.document 网页文档内的所有标签与内容;
- BOM(Browser Object Model): 专管浏览器外壳与操作系统交互(如 window.location 网址跳转、window.navigator 设备信息、window.history 前进后退)。

⚠️ 回流 (Reflow) 与 重绘 (Repaint)

性能杀手的底层根源

- 回流(Reflow): 改变了元素的几何尺寸(宽、高、位置),浏览器必须重新计算整棵树的布局,非常消耗 CPU;
- 重绘(Repaint): 只改变颜色、背景等外观,不影响几何位置,开销相对较小。

🎯 事件委托 (Event Delegation)

优雅性能优化的必修课

如果有 1,000 个列表项,千万不要给每个 <li> 单独绑定点击监听器!

利用事件冒泡原理,只需要在它们的父级 <ul> 绑定 1 个监听器,通过 event.target 识别是哪个子项被点击,内存占用狂降 99.9%!