JavaScript

浏览器 DOM 完整精讲(从原理、树结构、节点、操作到渲染、回流重绘)

DOM:Document Object Model,文档对象模型。

作者:洋柿子·2026-09-01·共 6 篇 · 当前 6

浏览器 DOM 完整精讲(从原理、树结构、节点、操作到渲染、回流重绘)

一、DOM 到底是什么

DOM:Document Object Model,文档对象模型。

浏览器把HTML 源代码,解析成一棵树形结构的 JavaScript 对象树。

一句话总结:

HTML 是文本,DOM 是浏览器把 HTML 翻译成的可被 JS 读写、修改、删除的对象模型。

只要 JS 想操作网页:改文字、改样式、增删标签、绑定事件,全靠 DOM。

二、DOM 核心本质

  1. HTML 字符串只是文本,JS 没法直接操作;
  2. 浏览器解析 HTML,生成 DOM 树;
  3. 每个 HTML 标签、文本、注释、属性,都是一个 DOM 节点;
  4. 整个网页在内存里就是一棵节点树。

三、DOM 节点 5 大类型(最核心)

整个 DOM 树全由节点组成,常用就这 5 种:

  1. 文档节点 document

    整棵树的根,全局唯一,JS 入口。

  2. 元素节点

    对应 HTML 标签:<div>、<p>、<span>,最常用。

  3. 文本节点

    标签里面的文字、空格、换行,单独算一个节点。

  4. 属性节点

    标签上的属性:class、id、src、href。

  5. 注释节点

    HTML 里 <!-- 注释 -->。

易错点:标签之间的换行、空格,在 DOM 里也是空白文本节点。

四、DOM 树结构示意

plaintext

document (文档根节点)
 └── <html> (元素节点)
      ├── <head>
      └── <body>
           ├── <div>
           │    └── 文本节点:你好
           └── <p>

层级关系:父节点、子节点、兄弟节点、祖先、后代。

五、DOM 四大核心操作(JS 常用)

1. 查:获取 DOM 元素

js

document.getElementById("id名")
document.getElementsByClassName("类名")
document.getElementsByTagName("div")
document.querySelector("#id / .class / 标签")  // 推荐
document.querySelectorAll()

2. 改:修改内容、属性、样式

js

// 改文本
dom.innerText = "文字"
dom.innerHTML = "<b>支持标签</b>"

// 改属性
dom.src = "图片地址"
dom.setAttribute("class", "box")

// 改样式
dom.style.color = "red"

3. 增:创建 + 插入节点

js

// 创建元素
let div = document.createElement("div")
// 插入到页面
document.body.appendChild(div)

4. 删 / 替换

js

dom.remove()          // 移除自身
父节点.removeChild(子节点)

六、浏览器渲染流程(DOM 必经之路)

  1. 浏览器解析 HTML → 生成 DOM 树
  2. 浏览器解析 CSS → 生成 CSSOM 样式树
  3. DOM + CSSOM 合并 → 渲染树 Render Tree
  4. Layout 布局(回流 / 重排):计算元素位置、宽高
  5. Paint 重绘:把像素画到屏幕
  6. Composite 合成:分层渲染,GPU 加速

七、重中之重:回流 & 重绘

1. 重绘 Repaint

只改颜色、背景、透明度,不改变宽高和位置,只重新画画,开销小。

2. 回流 / 重排 Reflow

改了宽高、边距、位置、显示隐藏,浏览器要重新计算整页布局,开销很大。

触发回流:

  • 修改宽高、margin、padding
  • 获取 offsetWidth、scrollTop 等布局属性
  • 增删 DOM 元素

优化原则:尽量少操作 DOM,减少回流重绘。

八、DOM 事件模型

DOM 事件分三个阶段:

  1. 捕获阶段:从 window 往下层层往下传递
  2. 目标阶段:触发当前点击的元素
  3. 冒泡阶段:从目标往上逐层往外冒

常用:事件冒泡、事件委托(给父级绑定事件,代理所有子元素)。

九、原生 DOM 的缺点 & 虚拟 DOM 由来

  1. 原生 DOM 操作很慢,DOM 对象属性极多;

  2. 频繁修改 DOM 会频繁触发回流重绘,页面卡顿;

  3. 于是 Vue/React 出了虚拟 DOM:

    用 JS 对象模拟 DOM 结构,先在内存对比差异,只更新变化的部分,减少真实 DOM 操作。