1. 苏葳的备忘录首页
  2. 因特网

浏览器中渲染树的构造

浏览器 渲染树当DOM树被构造的同时,浏览器构造了另外一棵树,渲染树。这是棵按其显示顺序排列的可视化元素构成的树。这是文档的可视化表现。这棵树的用途是允许以正确顺序绘制内容。Firefox把渲染树的元素称为“frame”。Webkit使用名称渲染者或渲染对象。一个“渲染者”知道如何布局并绘制它本身以及子元素。Webkit的RenderObject类,作为渲染者的基本类有以下定义:

class RenderObject{
   virtual void layout();
   virtual void paint(PaintInfo);
   virtual void rect repaintRect();
   Node* node; //the DOM node
   RenderStyle* style; // the computed style
   RenderLayer* containgLayer; //the containing z-index layer
}

每个渲染者表示一个矩形区域,通常对应于一个节点的CSS盒模型,正如CSS规范里描述的一样。它包含几何信息象宽度,高度和位置等。

盒类型被与节点相关的“display”样式属性影响(参见样式计算http://taligarsiel.com/Projects/howbrowserswork1.htm#style_computation一章)。这里是一段根据显示属性,决定为DOM节点创建哪种类型的渲染对象的Webkit代码:

RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
{
   Document* doc = node->document();
   RenderArena* arena = doc->renderArena();
   ...
   RenderObject* o = 0;
   switch (style->display()) {
      case NONE:
         break;
      case INLINE:
         o = new (arena) RenderInline(node);
         break;
      case BLOCK:
         o = new (arena) RenderBlock(node);
         break;
      case INLINE_BLOCK:
         o = new (arena) RenderBlock(node);
         break;
      case LIST_ITEM:
         o = new (arena) RenderListItem(node);
         break;
      ...
   }
   return o;
}

元素类型也被考虑在内,例如form控件和表格有特殊的frame。

在Webkit里如果一个元素想创建特殊的渲染者,那它将会覆盖“createRendered”方法。这个渲染者指向包含无位置信息的样式对象。

渲染树跟DOM树的关系

渲染者对应于DOM元素,但关系并不是一对一。非可见元素不会被插入渲染树。一个例子是“head”元素。显示属性设为“none”的元素也不会在此树中出现(元素是否可见的属性为“hidden”的会出现在树中)。

有些DOM元素对应于几个可视化对象。这些通常是有复杂结构的元素,不能被单个矩形描述。例如,“select”元素有三个渲染者—一个用于显示区域,一个用于下拉列表框,一个用在按钮上。另外当文本由于宽度无法被一行容纳而分割成多行时,新行会作为另一个渲染者添加进来。

另一个多渲染者的例子是未结束的HTML。根据CSS规范一个内联元素必须包含或者只有元素,或者只有内联元素。在混合内容的情况下,会创建一个匿名块渲染者以包含内联元素。

一些对应于DOM节点的渲染者不一定在树中的相应位置。浮动和绝对位置元素没按顺序来,放在树中不同的位置,映射到实际frame上。在它们本应放置的地方是一个frame占位符。

浏览器中渲染树的构造

图11:渲染树和对应的DOM树。“Viewport”是开始时包含的块。在Webkit里它是“RenderView”对象。

构造这棵树的流程

在Firefox里,表示层被注册成一个DOM更新的侦听器。表示层把frame创建委托给“FrameConstructor”,构造器解析样式(查看前述的样式计算)然后创建frame。

在Webkit里解析样式和创建渲染者的流程被称为“附加”。每个DOM节点有个“attach”方法。附加是同步的,节点插入DOM树时将调用新的“attach”方法。

处理html和body标签的过程构造了渲染树的根。根渲染对象对应于CSS规范所称的容器块—包含所有其它块的顶层块。它的尺寸是视口—浏览器窗口显示区域的大小。Firefox叫它ViewPortFrame,Webkit叫它RenderView。这些是文档中关于渲染对象的部份。树中的其它部份在DOM节点插入时生成。在http://www.w3.org/TR/CSS21/intro.html#processing-model处可以查看这个主题。

(待续)

原创文章,作者:苏葳,如需转载,请注明出处:https://www.swmemo.com/2064.html

发表评论

邮箱地址不会被公开。 必填项已用*标注