Skip to content

Document 与 DOM

Document 是浏览器为当前页面创建的文档对象,也是操作 DOM 的总入口。页面中的元素、文本、注释、属性等内容,最终都会以节点树的形式挂在这个文档对象之下。

先理解几个核心概念

Document

Document 表示整个文档本身。通常写的 document.querySelector()document.bodydocument.createElement(),本质上都在和 Document 打交道。

js
document
window.document

Node

Node 是更底层的抽象,表示 DOM 树中的任意节点。常见节点包括:

  • 文档节点:Document
  • 元素节点:Element
  • 文本节点:Text
  • 注释节点:Comment
js
document.nodeType // 9
document.body.nodeType // 1
document.body.firstChild?.nodeType

Element

Element 是节点的一种,专门表示 HTML 或 XML 中的元素,例如 <div><button><input>

js
const button = document.querySelector('button')

console.log(button instanceof Element) // true
console.log(button instanceof Node) // true

这三个概念的关系可以理解为:

  • Document 是整棵树的根入口。
  • Node 是整棵树里的通用节点模型。
  • Element 是最常操作的一类节点。

DOM 树是什么

浏览器解析 HTML 后,会把页面组织成一棵树状结构,也就是 DOM 树。

html
<body>
  <main>
    <h1>Hello</h1>
  </main>
</body>

这段结构会对应出大致这样的层级关系:

  • document
  • html
  • body
  • main
  • h1
  • Hello 对应的文本节点

理解 DOM 树之后,很多 API 就容易归类:

  • 查询:从树里找到目标节点
  • 遍历:在父子、兄弟之间移动
  • 操作:插入、删除、替换节点
  • 事件:在节点树上进行捕获和冒泡

Document 常见入口

最常见的几个入口属性如下:

js
document.documentElement // <html>
document.head // <head>
document.body // <body>

如果手里只有某个节点,也可以通过 ownerDocument 找到它所属的文档:

js
const el = document.querySelector('#app')

console.log(el.ownerDocument === document) // true

为什么很多 DOM API 都从 document 开始

因为 Document 承担了“当前页面文档上下文”的角色:

  • 负责查询页面中的节点
  • 负责创建新节点
  • 负责提供页面级状态,例如标题、焦点、可见性
js
const app = document.querySelector('#app')
const div = document.createElement('div')

div.textContent = 'hello'
app.append(div)

NodeElement 的区别

开发中最容易混淆的是“节点”和“元素”。

  • 节点范围更大,元素只是节点的一种。
  • childNodes 会包含文本节点和注释节点。
  • children 只包含元素节点。
js
const box = document.querySelector('.box')

console.log(box.childNodes)
console.log(box.children)

如果页面中的换行或空格被解析成文本节点,firstChildfirstElementChild 的结果就可能不同。

DocumentFragment 是什么

DocumentFragment 可以理解为“不直接挂在页面上的轻量文档片段”。它适合先在内存里组装一批节点,再一次性插入页面。

js
const fragment = document.createDocumentFragment()
const li = document.createElement('li')

li.textContent = 'item'
fragment.append(li)

它常用于批量插入,避免反复操作真实 DOM。

学习顺序建议

  • 先理解 DocumentNodeElement 的关系。
  • 再掌握查询、遍历和插入删除这些基础操作。
  • 之后再看事件、尺寸坐标、Observer 等专题能力。

相关页面:

  • /web/core/web-api/document/manipulating
  • /web/core/web-api/document/event
  • /web/core/web-api/document/size-offset
  • /web/core/web-api/document/coordinates
  • /web/core/web-api/document/observer

参考资料

基于 MIT 许可发布