特点
- CSS 对象众多(颗粒小而多)
- 计算频繁(为每个 Element 计算样式)
原理
每个 CSS 文件解析为样式表对象,每个对象包含 CSS 规则,CSS 规则对象包含选择器和声明对象,以及其他一些符合 CSS 语法的对象
Flex 和 Bison 解析生成器
- flex文件是定义 pattern
- 通过 flex 处理(词法分析)将输出切分成一段一段的 token
- 从而执行不同的 action
- tokens 交给 Bison 分析是否符合相关规则
过程
-
通过调用 CSSStyleSheet 的 parseString 函数,将上述 CSS 解析过程启动
使用解析生成器,然后回调函数
- createStyleRule
- 解析器达到某条件需要创建一个CSSStyleRule的时候将调用该函数
- 该函数的功能是创建一个Rule对象
- 并将其添加已解析的样式对象列表m_parsedStyleObjects中去
- reateCharsetRule,createImportRule,createMediaRule
-
解析完一遍后,把 Rule 都存储在对应的 CSSStyleSheet 对象中
-
转换成 CSSRuleSet
- 将所有的纯样式规则存储在对应的集合当中,这种集合的抽象就是 CSSRuleSet
- CSSRuleSet 提供了一个 addRulesFromSheet 方法,能将 CSSStyleSheet 中的 rule 转换为 CSSRuleSet 中的 rule
-
基于这些个 CSSRuleSet 来决定每个页面中的元素的样式
选择器解析顺序
- 从右往左
- 减少无效匹配次数,从而匹配快、性能更优
CSS 语法解析过程
- 先创建 CSSStyleSheet 对象将 CSSStyleSheet 对象的指针存储到 CSSParser 对象中
- CSSParser 识别出一个 simple-selector ,形如 “div” 或者 “.class”创建一个 CSSParserSelector 对象
- CSSParser 识别出一个关系符和另一个 simple-selecotr ,那么修改之前创建的 simple-selecotr, 创建组合关系符
- 循环第3步直至碰到逗号或者左大括号
- 如果碰到逗号,那么取出 CSSParser 的 reuse vector,然后将堆栈尾部的 CSSParserSelector 对象弹出存入 Vecotr 中,最后跳转至第2步如果碰到左大括号,那么跳转至第6步
- 识别属性名称,将属性名称的 hash 值压入解释器堆栈
- 识别属性值,创建 CSSParserValue 对象,并将 CSSParserValue 对象存入解释器堆栈
- 将属性名称和属性值弹出栈,创建 CSSProperty 对象并将 CSSProperty 对象存入 CSSParser 成员变量m_parsedProperties 中
- 如果识别处属性名称,那么转至第6步如果识别右大括号,那么转至第10步
- 将 reuse vector 从堆栈中弹出,并创建 CSSStyleRule 对象CSSStyleRule 对象的选择符就是 reuse vector, 样式值就是 CSSParser 的成员变量 m_parsedProperties
- 把 CSSStyleRule 添加到 CSSStyleSheet 中
- 清空 CSSParser 内部缓存结果
- 如果没有内容了,那么结束否则跳转值第2步
共享 computedStyle
-
该共享的element不能有id属性
-
tagName和class属性必须一样
-
mappedAttribute必须相等
-
一些可以影响CSS ComputedStyle的html属性
-
inlineStyleDeclaration
-
MappedStyleDeclaration
优先级比普通的CSS高,比inlineStyle要低
-
-
不能使用sibling selector,譬如:first-child, :last-selector, + selector
-
不能有style属性。哪怕style属性相等,他们也不共享
优化
- 不需要既指定 id 又指定 tagName
- 避免深层次的 node
- 慎用 ChildSelector
- 不要使用 attribute selector
- 理解依赖继承
- 规范
引擎
- jQuery Sizzle
- kquery
- nwmatcher
默认样式表
- html4UserAgentStyleSheet
- quirksUserAgentStyleSheet
- svgUserAgentStyleSheet
- sourceUserAgentStyleSheet