#How Broswers Work<二>渲染引擎--script(下)
来源:互联网 发布:淘宝客服操作流程 编辑:程序博客网 时间:2024/06/05 11:31
用规则做更简单的匹配
这里有几种关于样式规则的来源:
1.CSS规则,来至外部文件或在style标签里
`p {color:blue}`
2.内联的样式属性
<p style="color:blue" />
3.HTML中的可见属性(这将映射到相应的样式规则上)
<p bgcolor="blue" />
后面两个很容易匹配到元素,因为它们所拥有的样式属性和html属性可以将元素作为key进行映射。
就像前面问题2所提到的,css的规则匹配可能很狡猾,为了解决这个问题,可以先对规则进行处理,以使其更容易被访问。
解析完样式表后,规则被添加到几个hash映射中,根据选择器的分类,可分为id映射,class映射,tag映射以及其他的一些映射。如果选择器是id,则会被添加到id映射中,如果是class则会被添加到class映射中,以此类比。
这种操作会使元素更容易匹配规则,他没有必有查看每个规则-我们能从映射中提取相关的规则给这个元素,可排除95%没必要的规则,所以在匹配的过程中这些没必要的规则不会被考虑。
让我们看看下面这个样式的例子:
p.error {color:red}#messageDiv {height:50px}div {margin:5px}
第一条规则将被插入class映射,第二条插入id映射,第三条是标签映射。
下面这个html片段:
<p class="error">an error occurred </p><div id=" messageDiv">this is a message</div>
我们首先找到p元素对应的规则,class映射将包含一个“error”的key,找到p.error的规则,div在id映射和标签映射中都有相关的规则,剩下的工作就是找出这些由key对应的规则中哪些确实是正确匹配的。
例如,如果div的规则是
table div {margin:5px}
这也是标签映射产生的,因为key是最右边的选择符,但它并不匹配这里的div元素,因为这里的div没有table祖先。
Webkit和Firefox都会做这个处理。
以正确的级联顺序应用规则
样式对象拥有对应所有可见属性的属性,如果特性没有被任何匹配的规则所定义,那么一些特性可以从parent的样式对象中继承,另外一些使用默认值。
这个问题的产生是因为存在不止一处的定义,这里用级联顺序解决这个问题。
样式表的级联顺序
一个样式属性的声明可能在几个样式表中出现,或是在一个样式表中出现多次,因此,应用规则的顺序至关重要,这个顺序就是级联顺序。根据css2的规范,级联顺序为(从低到高):
浏览器声明
用户声明
作者的一般声明
作者的important声明
用户important声明
浏览器声明是最不重要的,用户只有在声明被标记为important时才会覆盖作者的声明。具有同等级别的声明将根据specifity以及它们被定义时的顺序进行排序。Html可视化属性将被转换为匹配的css声明,它们被视为最低优先级的作者规则。
specifity
选择器具体的定义参照CSS2的说明文档,如下:
1. 如果声明来自style属性,而不是一个选择器的规则,则计1,否则计(=a)
2. 计算选择器中id属性的数量(=b)
3. 计算选择器中class及伪类的数量(=c)
4. 计算选择器中元素名及伪元素的数量(=d)
把这四个数字串联一起a-b-c-d将得到specifity。
这里使用的基数由分类中最高的基数定义。例如如果a=14,你可以用16进制,不同情况下,a为17时,则需要使用阿拉伯数字17作为基数。之后的选择器可能会有如下的例子:html body div div p…(17个标签在你的选择器中,这好像不太可能)。
下面这些例子:
* {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
规则的排序
规则匹配之后,我们要根据级联顺序排序。Webkit对于比较小的链表用冒泡排序,比较大的用归并。webkit实现排序通过为这些规则重写“>”操作符:
static bool operator >(CSSRuleData& r1, CSSRuleData& r2){ int spec1 = r1.selector()->specificity(); int spec2 = r2.selector()->specificity(); return (spec1 == spec2) : r1.position() > r2.position() : spec1 > spec2; }
Gradual process
webkit有一个标志位用于确认高层的样式表已经被加载完成。如果样式在需要时没有完全被加载,这在文档中放占位符,等到样式全部被加载,再重新计算相应的值。
- #How Broswers Work<二>渲染引擎--script(下)
- How Broswers Work<二>渲染引擎-script解析(上)
- How Broswers Work<二>渲染引擎(1)
- How Broswers Work<二>渲染引擎(3)--HTML解析
- How Broswers Work<二>渲染引擎(3)--Layout
- How Broswers Work<二>渲染引擎--CSS解析
- How Broswers Work<二>渲染引擎(2)--解析的一般过程
- How Browsers Work<二>渲染引擎--painting
- DX11渲染引擎进展(二)
- How Does Shell Script Looping Work?(shell程序设计中的循环)
- [摘录]How browsers work之页面渲染流程
- linux下shell script学习(二)
- 浏览器工作原理(二):渲染引擎的详细介绍
- 浏览器原理(二)——渲染引擎
- 引擎系列学习【二】图形渲染管线
- Unity3D引擎之渲染技术系列二
- shell script in work
- 浏览器内核(渲染引擎)
- 地理坐标系统/投影坐标系统所有的WKID对应表
- iOS中用户未登录状态下点击下方tabBar触发登录
- springmvc学习笔记(4)-前端控制器
- 吉林大学1466
- springmvc学习笔记(5)-入门程序小结
- #How Broswers Work<二>渲染引擎--script(下)
- java获取项目运行根目录
- Cpp--改变形参指针无法实现双向传值的问题
- Linux和WINDOWS下JAVA代码实现,用命令行实现对apk包重新签名打包优化
- leetcode(20. Valid Parentheses)
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- Caffe上训练使用自己的数据
- 期末考试之考试传纸条
- javascript中的数组