render树由dom树与css树构成,dom树主要是为了描述内容,而css树则是描述对文档的样式规则;
构建流程:
浏览器将 DOM 和 CSSOM 合并成一个 渲染树,它会网罗网页上所有可见的 DOM 内容,以及每个节点的所有 CSSOM 样式信息。
-
从 DOM 树的根节点开始遍历每个可见节点
- 某些节点不可见(例如脚本标记、元标记等),因为它们不会体现在渲染输出中,所以会被忽略。
- 某些节点通过 CSS 隐藏,因此在渲染树中也会被忽略,例如,样式设置为
display: none属性的节点。
-
对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。
-
发射可见节点,连同其内容和计算的样式。
首先了解下什么是DOM树
浏览器将HTML解析成树形的数据结构,简称DOM;
DOM是文档对象模式(Document Object Model)的缩写;是HTML文档的对象标识;解析树的根节点是Document对象;
节点:Node--构成HTML文档最基本的单元;
常用节点分为四类;
1、文档节点:整个HTML文档;
2、元素节点:HTML文档中的HTML标签;
3、属性节点:元素的属性;
4、文本节点:HTML标签中的文本内容;
5、注释节点
childNodes包含了哪些节点?
由childNodes属性返回的数组中包含着所有类型的节点,所有的属性节点和文本节点也包含在其中。
事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释成节点。而且都包含在childNodes属性所返回的数组中。
chidNoeds返回的事node的集合,
每个node都包含有nodeType属性。
nodeType取值:
元素节点:1
属性节点:2
文本节点:3
注释节点:8
let nodeRoot = document; //根节点
let nodeHTML = nodeRoot[1]; // html节点
let nodeHead = nodeHTML.childNodes[0] // head节点
let nodeBody = nodeHTML.childNodes[1] // body节点
let nodeDiv = nodeBody.childNodes[0] //DIV节点
let nodeText = nodeDiv.childNodes[0] // 文本节点
strText = nodeText.data //文本节点有data这个属性
可以看下DOM树的基本结构:
说明:
1.跨域除外,跨域通常是在操作frame 上,简单的说,就是两个frame 不属于同一域名
2.上面的操作为了演示,采用的方法是从根结点一直到文本结点的遍历,在DOM 方法上,有更简洁的方法,这些以后会有更多示例加以说明。
3.DOM树揭示了DOM对象之间的层次关系,这样就方便动态地对html文档进行增删改查。
4.增删改查必须要遵循层次关系
5.文本对象是最底层的节点
6.获取 对象的值 .data
CSS树
主要是对每个节点进行样式描述!
渲染对象是和 DOM 元素相对应,但这种对应关系并非一一对应,因为有这么些特殊元素:
非可视化元素:非可视化的 DOM 元素不会被插入渲染树中;
如<head> 标签以及里面的内容,以及 display:none 的元素也会被去除,但是 visibility: hidden ,opacity: 0的元素仍会显示;
复杂结构元素:
例如, select 元素有 3 个渲染器:一个用于显示区域,一个用于下拉列表框,还有一个用于按钮。如果由于宽度不够,文本无法在一行中显示而分为多行,那么新的行也会作为新的呈现器而添加。
另一个关于多渲染器的例子是格式无效的 HTML。根据 CSS 规范,行内元素只能仅包含块状元素或行内元素中的一种。如果出现了混合内容,则应创建匿名的块状渲染对象,以包裹行内元素。所以我们平时的 inline-block 可以设置宽高。
脱离文档流:
部分渲染对象对应于 DOM 节点,但树中所在的位置与 DOM 节点不同。例如,浮动定位和绝对定位的元素处于正常的文本流之外,在两棵树上的位置不同,渲染树上标识出真实的结构,并用一个占位结构标识出它们原来的位置。
样式计算
构建渲染树之前,需要计算每一个渲染对象的可视化属性。这是通过计算每个元素的样式属性来完成的。
样式包括来自各种来源的样式表、行内样式元素和 HTML 中的可视化属性。其中后者经过转化以匹配 CSS 样式属性。
样式表的来源包括浏览器的默认样式表、由网页作者提供的样式表以及由浏览器用户提供的用户样式表(浏览器允许您定义自己喜欢的样式。以 Firefox 为例,用户可以将自己喜欢的样式表放在 Firefox Profile 文件夹下)。
样式计算存在以下难点:
- 样式数据是一个超大的结构,存储了无数的样式属性,这可能造成内存问题。
- 如果不进行优化,为每一个元素查找匹配的规则会造成性能问题。要为每一个元素遍历整个规则列表来寻找匹配规则,这是一项浩大的工程。选择器会具有很复杂的结构,这就会导致某个匹配过程一开始看起来很可能是正确的,但最终发现其实是徒劳的,必须尝试其他匹配路径。
- 应用规则涉及到相当复杂的层叠规则(用于定义这些规则的层次)
了解了以上知识点后,再总结一下大概的构建流程:
DOM 树和 CSSOM 树将合并后在浏览器屏幕上渲染像素
- DOM 树与 CSSOM 树合并后形成渲染树
- 渲染树只包含渲染网页所需的节点
- 布局计算每个对象的精确位置和大小
- 最后一步是绘制,使用最终渲染树将像素渲染到屏幕上