概述
DOM 是用来生成网页页面的数据结构,它为 js 提供了操作的接口,通过这些接口,js 可以对 DOM 进行访问,从而能够改变网页的结构、内容和样式
流程
DOM 树构建
- 请求网页得到页面的 HTML 字节流文件
- 分词器将字节流转化为 Token
- 把 Token 转变为节点对象 Node
- 将节点对象连接在一起,形成 DOM 树
更详细的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>DOM</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="index.js"></script>
</body>
</html>
- 浏览器请求 HTML 文件,返回后开始解析,构建 DOM
- 遇到请求 CSS 的 link 标签开始请求和解析 CSS,构建 CSSOM,同时继续解析 HTML
- 遇到请求 js 的 script 标签,请求和解析 js 文件并阻塞 HTML 文件的解析
- js 文件和 CSS 文件的返回时间无法确定,但 js 代码的运行要在构建完 CSSOM 之后
- CSSOM 构建完毕开始运行 js,js 将操作 DOM 和 CSSOM
- js 操作完毕继续解析 HTML文件构建 DOM
- DOM 构建完毕后开始构建渲染树,接下来是布局然后绘制网页
- 后续 js 操作之后会再次构建渲染树、布局绘制网页
中间的一些细节
为什么 HTML 文件是边加载边解析的?
因为 HTML 文件的解析不是全部接收完才开始解析构建 DOM 树的,而是与服务器或本地创建一个管道,每隔一段时间读一次数据,然后把这些数据解析成 DOM
为什么遇到 script 标签时需要暂停 HTML 文件解析?
因为 js 是可以操作 DOM 和 CSSOM 的,如果允许继续解析,会出现页面内容出现了又被 js 改变了的情况,这种情况显然是异常的。