Skip to content

DOM 编程:节点、查询、修改与渲染影响 ​

> 视频入口:B站合集《前端全链路:从浏览器基础到现代生态》上传并核验后回填正式链接。 > 本文是 EP12 的博客深讲版,包含视频主线,但比视频补充更多机制、流程图、边界判断和排查清单。

DOM 编程:节点、查询、修改与渲染影响 技术流程图

这篇文章解决什么问题 ​

这期解释 DOM 编程怎样让 JavaScript 读取和修改页面结构,以及这些修改怎样影响浏览器渲染。

这一篇的中心问题可以概括成:DOM 编程怎样让 JavaScript 读取、修改页面结构并影响渲染?

关键词:DOM、document、node、element、querySelector、data attribute、textContent、setAttribute、classList、innerHTML

视频主线回顾 ​

1. DOM 是节点树 ​

浏览器把 HTML 解析成 document 入口下的节点树,JavaScript 操作的是这些节点对象。

2. 查询要稳定 ​

querySelector 很方便,但选择器应该基于稳定语义或 data 属性,避免依赖脆弱层级。

3. 修改要明确 ​

文本用 textContent,属性用 setAttribute,样式状态用 classList,结构用 createElement 和 append。

4. DOM 修改会影响渲染 ​

节点变化可能触发样式计算、布局和绘制。批量修改通常比读写交错更稳。

技术流程图 ​

先用一张图把本期内容串起来。它不是背诵路线,而是排查问题时可以顺着走的证据路线。

mermaid
flowchart TD
    s1["本期内容:DOM 是 JavaScript 操作页面的结构接口"]
    s2["节点树:HTML 会被解析成 DOM 节点树"]
    s3["查询节点:querySelector 用 CSS 选择器找到元素"]
    s4["修改内容:修改 DOM 要分清文本、属性和结构"]
    s5["创建节点:创建节点比拼字符串更可控"]
    s6["渲染影响:DOM 修改可能触发样式、布局和绘制"]
    s7["整体总结:DOM 是页面结构的可编程入口"]
    s1 --> s2
    s2 --> s3
    s3 --> s4
    s4 --> s5
    s5 --> s6
    s6 --> s7
    s7 --> check{"能否解释当前页面现象?"}
    check -->|能| action["记录证据并进入下一步"]
    check -.->|不能| back["回到上一层重新定位"]
    back -.-> s1

深入展开 ​

1. DOM 是 JavaScript 操作页面的结构接口 ​

这一期看 DOM 编程。我们会讲 document、节点树、querySelector 查询、文本和属性修改、classList 切换样式、创建和插入节点,以及 DOM 修改对样式计算、布局和绘制的影响。理解 DOM,才能知道为什么框架最后还是要把组件结果落到真实页面上。

这里可以多看一层:先找输入,再看处理过程,最后确认输出。前端很多问题之所以绕,是因为现象出现在页面上,原因却可能藏在网络、样式计算、运行时或构建结果里。

mermaid
flowchart LR
    v1["查询:找到节点"]
    v2["读取:拿到文本和属性"]
    v3["修改:更新结构和样式入口"]
    v4["渲染:触发后续计算"]
    v1 --> v2
    v2 --> v3
    v3 --> v4

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

2. HTML 会被解析成 DOM 节点树 ​

浏览器解析 HTML 后,会得到一棵 DOM 节点树。document 是入口,html、body、div、button 是元素节点,文字内容是文本节点。我们在 JavaScript 里操作的不是 HTML 字符串本身,而是这棵树上的对象。节点有父子、兄弟和属性关系,页面结构也因此能被脚本遍历和修改。

把这段机制放到工程里看,最实用的切口是证据。不要急着猜是哪一行代码错了,先确认浏览器或工具实际拿到了什么、计算了什么、丢出了什么结果。

维度含义
document整棵树的入口。
element标签对应的节点对象。
text标签之间的文字节点。

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

3. querySelector 用 CSS 选择器找到元素 ​

querySelector 和 querySelectorAll 可以用 CSS 选择器查找元素。比如 document.querySelector("[data-submit]") 找到提交按钮。实际项目里,不建议依赖很脆的层级路径;更稳的是用语义元素、id、class 或 data 属性作为查询入口。查到节点以后,才能读取文本、绑定事件或修改状态。

这个点在真实项目里常常不是孤立问题。它会和状态、缓存、布局、依赖或团队约束连在一起,所以博客版更强调边界:什么归它管,什么应该交给下一层机制判断。

js
const button = document.querySelector("[data-submit]");
const items = document.querySelectorAll(".todo-item");
  • querySelector 返回第一个匹配元素。
  • querySelectorAll 返回静态列表。
  • data-* 适合做行为标记。

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

4. 修改 DOM 要分清文本、属性和结构 ​

修改 DOM 时,要分清修改的是文本、属性、样式类名还是结构。textContent 改文本,setAttribute 改属性,classList 切换类名,append 可以插入新节点。innerHTML 虽然方便,但会重新解析字符串,并带来安全风险。日常优先用明确 API 表达意图。

如果要把它讲给别人听,可以按“现象—证据—机制—边界”的顺序。先让对方看到问题,再解释浏览器或工具为什么会给出这样的结果。

维度含义
textContent更新可见文字。
setAttribute更新属性和语义信息。
classList切换 CSS 状态。

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

5. 创建节点比拼字符串更可控 ​

创建结构可以用 document.createElement,再设置文本、属性和类名,最后 append 到目标容器。这样做比拼接 HTML 字符串更可控,也更容易避免把用户输入当成 HTML 解析。大量插入时,可以先用 DocumentFragment 组装,再一次性放进页面,减少中间状态带来的开销。

这里可以多看一层:先找输入,再看处理过程,最后确认输出。前端很多问题之所以绕,是因为现象出现在页面上,原因却可能藏在网络、样式计算、运行时或构建结果里。

js
const li = document.createElement("li");
li.textContent = title;
li.classList.add("todo-item");
list.append(li);
  • 创建元素节点。
  • 用 textContent 放文本。
  • 最后插入目标容器。

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

6. DOM 修改可能触发样式、布局和绘制 ​

DOM 修改之后,浏览器可能重新计算样式、布局和绘制。改 class 可能影响样式,插入节点可能影响布局,读取 offsetWidth 这类布局信息时,浏览器可能被迫先把前面的修改计算完。性能优化不是不改 DOM,而是避免频繁读写交错,尽量把修改批量处理。

把这段机制放到工程里看,最实用的切口是证据。不要急着猜是哪一行代码错了,先确认浏览器或工具实际拿到了什么、计算了什么、丢出了什么结果。

mermaid
flowchart LR
    v1["DOM 变化:节点或属性改变"]
    v2["样式计算:规则重新匹配"]
    v3["布局:尺寸和位置更新"]
    v4["绘制:画到屏幕上"]
    v1 --> v2
    v2 --> v3
    v3 --> v4

排查时可以顺着这条线问:当前现象是输入不对、处理过程不对,还是最终结果不对。只要能把问题归到其中一格,后面的工具选择就会轻很多。

常见误区与边界 ​

  • 不要把 DOM 当成字符串拼接目标。
  • 不要忽略 innerHTML 的安全风险。
  • 不要频繁交错读写布局信息。
  • 这一篇不展开:虚拟 DOM diff 细节,留到框架批次。
  • 这一篇不展开:复杂渲染性能剖析,留到性能单集。
  • 这一篇不展开:Web Components 深度实践。

排查和验证清单 ​

  • 先确认问题发生在哪一层:页面结构、样式计算、JavaScript 运行、网络请求、构建产物还是线上交付。
  • 用浏览器或工具拿到证据,不只凭肉眼判断。能截图、能看到日志、能看到请求和产物,结论才稳。
  • 把最小例子缩到只剩一个变量。变量越少,越容易看清机制。
  • 记录输入、处理过程和输出。前端问题往往不是“某个 API 错了”,而是链路中某一步的假设不成立。
  • 如果准备把结论放到项目里,再补一层测试、类型检查、可访问性或性能验证。

动手练习 ​

  1. 用一个最小 HTML 页面复现 DOM 编程 里的核心现象。
  2. 打开 DevTools,分别记录结构、样式、控制台、网络或性能面板里的一个证据点。
  3. 改一个变量,再观察结果是否符合这篇文章里的流程图;如果不符合,把差异写下来。

参考来源与本系列依据 ​

  • 标准:DOM Standard:节点、文档和 API 基线
  • 浏览器文档:MDN DOM / Document APIs:开发者解释
  • 工具:Chrome DevTools Elements / Performance:验证修改和渲染影响

总结 ​

DOM 是 JavaScript 操作页面的结构接口。查到节点、明确修改、理解渲染影响,是写可靠交互的基础。

博客版到这里就把视频主线扩成了可复习的技术笔记:先知道它在链路里的位置,再知道它怎么运行,最后知道遇到问题该从哪里查。

别急,先让缓存热一下。