CSS选择器从右向左的匹配规则
CSS选择器从右向左的匹配规则
下面这个栗子,CSS选择器它是如何工作的?
.mod-nav h3 span {font-size: 16px;}
如果不知道匹配规则,可能的理解是从左向右匹配:先找到.mod-nav,然后逐级匹配h3、span,在这个过程中如果遍历到叶子节点都没有匹配就需要回溯,继续寻找下一个分支。
但事实上,CSS选择器的读取顺序是从右向左。
还是上面的选择器,它的读取顺序变成:先找到所有的span,沿着span的父元素查找h3,中途找到了符合匹配规则的节点就加入结果集;如果直到根元素html都没有匹配,则不再遍历这条路径,从下一个span开始重复这个过程(如果有多个最右节点为span的话)。
在某条CSS规则下(比如.mod-nav h3 span),会形成一条符合规则的索引树,树由上至下的节点是规则中从右向左的一个个选择符匹配的节点。索引树遍历的具体过程可以看寒冬大大的一段视频。
为什么从右向左的规则要比从左向右的高效?

假如DOM的结构如上图,匹配规则是.mod-nav h3 span。
若从左向右的匹配,过程是:从.mod-nav开始,遍历子节点header和子节点div,然后各自向子节点遍历。在右侧div的分支中,最后遍历到叶子节点a,发现不符合规则,需要回溯到ul节点,再遍历下一个li-a,假如有1000个li,则这1000次的遍历与回溯会损失很多性能。
再看看从右至左的匹配:先找到所有的最右节点span,对于每一个span,向上寻找节点h3,由h3再向上寻找class=mod-nav的节点,最后找到根元素html则结束这个分支的遍历。
很明显,两种匹配规则的性能差别很大。之所以会差别很大,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。
当然这是比较明显情况,如果在叶子上存在多个不符合条件的span,从右向左的规则也会走一些弯路(这时就需要优化CSS选择器了)。但平均来说它还是更高效,因为大多时候,一个DOM树中,符合匹配条件的节点(如.mod-nav h3 span)远远远远少于不符合条件的节点。
jQuery从1.3版本开始使用的Sizzle引擎,它按照了CSS选择器的匹配规则(从右至左)进行DOM元素的查找与匹配(当然其中做了很多优化),性能得到了很大的提升。
欢迎批评指正。
[创新工场2014] 2014创新工场校园招聘笔试题
继上一篇博文《[创新工厂2014]回文修复》后,继续推出第二道创新工厂的笔试算法题~
对于非负数列a1、a2、......、an,在数轴上做垂线连接点(i,0)和(i,ai)。选择这样的两条线和x轴可以形成一个容器,我们以面积代表所装的水,求以这种方式构成的容器能装的最大面积。比如选择a2=3、a5=6,则所装的面积为9。
分析:
这道题实际上的意思是:对于一个给定的序列,求abs(i-j)*min(a[i],a[j])的最大值!
先对序列按照高度排序,然后按照排序后的顺序进行枚举,枚举过的就做标记,表示已经访问过了,保证了当前的节点,是序列里的最小高度的板,那么以这个板为边界能装的最大的水,肯定就是当前序列的最左边,或者最右边,因为没有其他板比当前板更矮了,分别计算,并且update最大值。
如果当前这个节点就是边界,且已经访问过(即比当前的节点的高度更小),那么就要对L和R进行收缩,保证L和R是当前节点能构成最大容器的最远边界。
代码如下:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <limits.h>
using namespace std;
#define max(a,b) a>b?a:b
typedef struct Pair{
int i;
int ai;
}Pair;
Pair p[101];
int n;
int flag[101];
bool cmp(Pair a,Pair b)
{
if(a.ai<b.ai)
return true;
else
return false;
}
int main()
{
freopen("b3.in","r",stdin);
freopen("b3.out","w",stdout);
int maxRes;
int L,R;
while(scanf("%d",&n)!=EOF)
{
memset(flag,0,sizeof(flag));
maxRes = INT_MIN;
for(int i=0; i<n; i++)
{
scanf("%d",&p[i].ai);
p[i].i = i;
}
sort(p,p+n,cmp);
L=0;
R=n-1;
for(int i=0; i<n; i++)
{
flag[p[i].i] = 1;
maxRes = max(maxRes,abs(L-p[i].i)*p[i].ai);
maxRes = max(maxRes,abs(R-p[i].i)*p[i].ai);
if(p[i].i==L)
{
while(flag[L]==1) L++;
}
if(p[i].i==R)
{
while(flag[R]==1) R--;
}
}
printf("%d\n",maxRes);
}
return 0;
}
如果有错误的地方,还望大家及时指出,谢谢~
CSS选择器从右向左的匹配规则的更多相关文章
- 正则表达式从右往左进行匹配(Regex)
#匹配最末两位为数字 $x=New-Object regex ('\d{2}','RightToLeft') #$x.RightToLeft $x.Match('abcd22') 结果:
- CSS选择器性能分析
写了几篇关于js的博客,也是关于性能的,现在,我觉得有必要那css来认真分析一下了.之前只是看别人这么写就跟着写,但是没有去研究这样写或者是不是正确的写法,性价比怎么样,渲染的效率好么!这些都没有考虑 ...
- css选择器选择顺序是从右往左的,为什么?
https://segmentfault.com/q/1010000000713509 为什么 CSS 选择器解析的时候是从右往左? CSS 的后代选择器本身就是一种在标准里面不那么推荐的方式. 首先 ...
- CSS选择器、优先级与匹配原理
为了分析Bootstrap源码,所以的先把CSS选择器相关的东东给巩固好 废话就不多说了 CSS 2.1 selectors, Part 1 计算指定选择器的优先级:重新认识CSS的权重 标签的权值为 ...
- CSS选择器、优先级与匹配原理(转)
CSS选择器.优先级与匹配原理 导航 为了分析Bootstrap源码,所以的先把CSS选择器相关的东东给巩固好 废话就不多说了 CSS 2.1 selectors, Part 1 计算指定选择器的优先 ...
- 如何提升 CSS 选择器性能
CSS 选择器性能损耗来自? CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器.而在这之前我们需要了解CSS选择器匹配 ...
- CSS选择器渲染效率
1 浏览器如何识别你的选择器 首先我们需要清楚,浏览器是如何读取选择器,以识别样式,并将相应的样式附于对应的HTML元素,达到美化页面的效果.Chris Coyier曾在<Efficiently ...
- CSS选择器的优化
前面花了几个篇幅着重介绍了CSS的选择器的使用,我将其分成三个部分:CSS基本选择器.CSS属性选择器以及CSS伪类选择器.那么今天我主要想和大家一起来学习——CSS选择器方面的性能优化.因为对性能这 ...
- 提升 CSS 选择器性能的方法
CSS 选择器性能损耗来自? CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器.而在这之前我们需要了解CSS选择器匹配 ...
随机推荐
- ASP.NET MVC 使用TryUpdateModel 更新的技巧
有使用 ASP.NET MVC 的朋友應該會對於 TryUpdateModel 有一定的認知,他不但可以利用 Metadata 來做欄位的驗證確保資料的正確性,也可以指定更新的條件以及不更新的條件來達 ...
- JavaScript之再谈回调与闭包
前些阵子写了几篇关于回调和闭包的博文,感觉自己都是似懂非懂,最近在项目中又碰到了类似的情况,故在此咱们来重弹js中的回调与闭包. 先说说回调: 百度百科: 回调函数就是一个通过函数指针调用的函数.如果 ...
- crawler_网络爬虫中编码的正确处理与乱码的解决策略
转载: http://hi.baidu.com/erliang20088/item/9156132bdaeae8949c63d134 最近一个月一直在对nutch1.6版进行中等层次的二次开发,本来是 ...
- Effective C++ 18-23
18.接口用于完整的类,使最小. 用户接口类是指程序猿这个类可以访问所获得的接口,典型接口具有在存在唯一功能,好的包装类的数据成员. 这意味着一个完整的接口,包括所有 合理的功能操作.最小指功能和特征 ...
- 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据
原文:[百度地图API]如何利用地图API制作汽车沿道路行驶的动画?--如何获得道路层数据 有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画.可是,百度地图的道路数据并没有公开 ...
- [CLR via C#]4. 类型基础及类型、对象、栈和堆运行时的相互联系
原文:[CLR via C#]4. 类型基础及类型.对象.栈和堆运行时的相互联系 CLR要求所有类型最终都要从System.Object派生.也就是所,下面的两个定义是完全相同的, //隐式派生自Sy ...
- REUSEADDR 选项
一般而言,对于处理2MSL状态的套接字(一般为服务端套接字)是不允许接受从同一客户端重新发起一个新的连接的,但是套接字编程系统接口允许应用程序通过设置一个REUSEADDR选项,使处于2MSL状态的套 ...
- bootstrap-wysiwyg 结合 base64 解码 .net bbs 图片操作类 (三) 图片裁剪
官方的例子 是 长方形的. 我这里 用于 正方形的头像 所以 做如下 修改 #preview-pane .preview-container { width: 73px; height: 73px ...
- Android的5样的调试信息
Android的5样的调试信息 华清2014-10-23 北京海淀区 张俊浩 verbose:只是滤全部的信息. 啰嗦的意思. debug:debug调试的意思. info:一般提示的信息inf ...
- 11g R2RAC Dynamic remastering
In this post, I will demonstrate dynamic remastering of the resources in RAC . In RAC, every data bl ...