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

浏览器中使用规则树来计算样式

浏览器 样式 计算当计算某个元素的样式内容时,我们首先计算规则树里的一条路径或是使用一条已经存在的路径。接下来就开始应用路径中的规则来填充我们新的样式内容的结构。我们从路径的底部结点开始—优先级最高的(通常是最精确的选择器)并往上遍历树,直到结构填满。如果规则节点中没有找到结构的匹配,那么我们就能进行充份的优化—我们沿树而上直到发现一个节点完全匹配,然后指向它—这是最好的优化策略—整个结构都被共享。这能简化最终值的计算并能节约内存。

如果我们找到了部份定义,我们沿树而上直到结构被填满。

如果我们没有发现任何一个我们结构的定义,那么在结构是“继承”类型的情况下—我们指向内容树中节点的父结构,这种情况下我们也能成功共享结构。如果它是个reset结构那么将使用缺省值。

如果大多数具体结点需要添加值,那么我们需要进行一些额外的计算来把它们转成实际值。我们然后就把结果缓存到树节点里,这样就能被子节点使用。

在某个元素有个指向同一树节点的亲属或兄弟节点的情况下,完整的样式内容可以在它们间共享。

让我们看个例子:假设我们有下面HTML

<html>
<body>
<div class="err" id="div1">
<p>
this is a <span class="big"> big error </span>
this is also a
<span class="big"> very big error</span> error
</p>
</div>
<div class="err" id="div2">another error</div>
</body>
</html>

和下面的规则:

1. div {margin:5px;color:black}
2. .err {color:red}
3. .big {margin-top:3px}
4. div span {margin-bottom:4px}
5. #div1 {color:blue}
6. #div 2 {color:green}

简单起见我们假设只需要填充两个结构—color结构和margin结构。color结构只包含一个成员—颜色。margin结构包含四个边。

结果规则树看起来跟下面类似(节点用节点名标注:它们指向的#规则)

浏览器中使用规则树来计算样式

图12:规则树

内容树看起来象这样(节点名:它们指向的规则节点)

浏览器中使用规则树来计算样式

图13:内容树

假设我们处理HTML,到达了第二个<div>标签。我们需要为这个节点创建样式内容并填充样式结构。

我们会匹配规则,发现与<div>匹配的规则是1,2和6.这意味着树里面已经有了我们的元素能使用的已经存在的路径,我们只需要为规则6另外增加一个节点(规则树中的节点F)。

我们会创建一个样式内容并把它放进内容树。新的样式内容会指向规则树里的节点F。

现在我们需要填充样式结构。我们从填充margin结构开始。因为最后的规则节点(F)不会添加到margin结构,我们可以沿树往上直到找到一个在先前节点插入时计算过的缓存的结构并使用它。我们会找到节点B,它是最靠上的匹配margin规则的节点。

我们有color结构的定义,所以我们不能使用一个缓存结构。因为color只有一个属性,我们不需要沿树往上填充其它属性。我们会计算最终值(把字符串转换成RGB值)并在节点中缓存计算过的结构。

在第二个<span>处的工作甚至更为简单。我们会匹配规则,得出结论它应指向规则G,象前一个span一样。因为我们有亲属节点指向同一个节点,我们可以共享整个样式内容并指向前一个span的内容。

对于包含有继承自父节点规则的结构,缓存在内容树里完成(color属性实际上是继承的,但Firefox把它处理成reset的,并把它在规则树里缓存)。

例如如果我们为某段的字体增加了规则:

p {font-family:Verdana;font size:10px;font-weight:bold}

然后div元素,作为内容树里段落的子元素,可以跟它的父元素共享同样的字体结构。这只会在“div”没有被指定字体规则时发生。

在Webkit里,并没有一个规则树,匹配的声明会遍历4次。首先是非关键高优先级的属性(指需要首先被应用的属性,因为其它属性依赖于它—象display)先被应用,然后是高优先级关键属性,然后是一般优先级非关键属性,最后是一般优先级关键规则。这意味着出现多次的属性将会依据正确的级联次序得到解析。最后一次胜出。

那么总结一下—共享样式对象(他们中的全部或部份结构)解决问题1和问题3。Firefox的规则树也有助于以正确顺序应用这些属性。

(待续)

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

发表评论

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