Webkit内核-Render树
RenderObject类
RenderObject是Render树的节点基础类,提供了一组公共的接口。
在DOM树中,分为“可视节点”与“非可视节点”,比如”head”、“script”就是典型的“非可视节点”,而“body”、“div”、“canvas”等这些节点通常情况下为“可视节点”,这些节点会呈现一块区域。
对于“可视节点”,Webkit会为他们创建相应的RenderObject对象,一个RenderObject对象保存了为绘制DOM节点所需要的各种信息,如样式布局信息,元素颜色信息。页面上所有的节点构成了RenderObject树,这里要注意,RenderObject树节点和DOM节点不是一一对应关系,下边三个原则会被创建RenderObject节点:
- DOM树的document节点;
- DOM树中的“可视节点”;Webkit不会为非可视节点创建RenderObject节点;
- 某些情况下Webkit匿名RenderObject节点,这些节点不应用于DOM树中的节点,典型的例子是RenderBlock节点。
匿名RenderBlock对象
CSS中有块级元素和内嵌(inline)元素之分。内嵌元素表现的是行布局形式,就是说这些元素以行进行显示。以 div 元素为例,如果设置属性 style 为 display:inline 时,则那是内嵌元素,那么它可能与前面的元素在同一行;如果该元素没有设置这个属性时,则是块级元素,那么在新的行里显示。
RenderBlock用来是用来表示块级元素, 为了处理上的方便,某些情况下需要建立匿名的RenderBlock对象,因为RenderBlock的子女必须都是内嵌的元素或者都是非内嵌的元素。所以,当它包含两种元素的时候,那么它会为相邻的内嵌元素创建一个块级RenderBlock节点,然后设置该节点为自己的子女并且设置这些内嵌元素为它的子女。
影子DOM
对于影子DOM,就是在DOM节点中还没有实际appendChild的节点,它可能是由createElement方法产生的内容,Javascript代码没有办法访问影子DOM,Webkit需要创建并渲染RenderObject对象,但是不需要把它转换为RenderObject节点。
Element类
RenderObject对象包含Element类,每个Element对象都会递归调用”attach”函数,该函数检查Element对象是否需要创建RenderObject节点,如果需要会使用NodeRenderingContext类来根据DOM节点的类型来创建RenderObject节点。
层次和RenderLayer对象
网页是可以分层的,这有俩点原因,一是方便网页开发者开发网页并设置网页层次,二是为了Webkit在处理时更便捷。
在某些类型的RenderObject节点或具有某些CSS样式的RenderObject节点出现时,Webkit就会为这些节点创建RenderLayer对象。RenderLayer创建的基本原则如下:
- DOM树中Document节点对应的RenderView节点;
- DOM树中的Document的子女节点,也就是HTML节点对应的RenderBlock节点;
- 显示的指定CSS位置的RenderObject节点;
- 有透明效果的RenderObject节点;
- 节点有溢出(overflow)、alpha或反射等效果的RenderObject节点;
- 使用Canvas 2D和3D(WebGL)技术的RenderObject节点;
- Video节点对应的RenderObject节点。
为了直观感受这三种树,如下给出了这三种树及其它们之间的对应关系:
由此可见他们三者相互之间并不是一一对应的关系。
欢迎关注公众号,我们会不定期分享前沿技术、学习资料,在前端的道路上一起成长