初探 jQuery 的 Sizzle 选择器 发布日期:2010年7月15日
开始吧。($符在这里不作过多的介绍).
当我们给$符传递进一个参数(也可能是多个)时,此时它会根据参数的类型(domElement | string | fn | array)进入不同的流程,在此,重点看 string 类型的处理,因为只有它才可以触发Sizzle。首先调用正则匹配看是否为创建dom节点的操作,然后看是否为简单id匹配,这一步也由正则匹配完成,否则进入jQuery.fn.find()函数,由此进入Sizzle的天地。
当进入Sizzle时,一般情况下会配备三参:所要匹配的选择符,上下文,匹配的结果集。调用正则对传入的selector做一次”预匹配”.
set ? ? //直接用就可以了$('div:hasSpan')....比较再拾YUI3,在经过大幅度变化,以全新姿态出现,从选择器上的执行上效率不逊色于Sizzle几毫,初看YUI时就一直对它的模块细粒度化赞不绝口,但是从如我这样的实用主义者的角度来看,选择器就应该是一个单独的模块,就如同jQuery分离而出的Sizzle。但在YUI term眼里,为了让代码的组织结构看上去更加的理想化,更加具有”YUI3“的特色,将之在代码结构上又细分出一二三,比起Sizzle的简洁,它显得太过学院派。
除此,在选择器的扩展上,sizzle表现胜于YUI3 selector,在实现css1~css3选择器的基础上,又对常用的功能进行了扩展。比如对表单元素快捷操作。据我所知,开发者对这类型选择器的使用频率并不是想象中那么低。既然有了模块的细分,为什么不将这部分作为一个可扩充性的功能点模块融入框架中呢。Sizzle于开发者就如同一块可口味佳的点心,满足我们各式各样的胃口,简洁,不失其功能的强劲,这点非常值得称道。
总得来看,Sizzle与YUI就好象一个面向实际与理想主义的比较。这里没有对错之分,从不同角度来看,都能略窥其各自的禅意。前者从如何为开发者带来便利的角度考虑,让开发者实时觉得它的简单可信赖。后者,也寄托了自己对web的构想,如果浏览器原生全部支持css3-selector,那岂不是完全不用引入该模块了,不过我想,真到那时候,各框架也都会有很大的变化了,只是我对这一天的到来抱有比较消极的态度,这是后话。
总结本文从总体上讨论了jQuery之Sizzle选择器的实现原理,通过一个初步的流程分析,让各位读者对此有一个大致印象,毫无疑问,更深层次的匹配,也只是它的递归调用,再匹配而已。
这里,没有做与其他框架在效率上的比较,如果你还对它的效率还有所怀疑的话,你可以自行比较。
如果你感兴趣,更推荐你继续去探索在1.4中着重优化的api源码,或许,会给你更多的启示
思考从jQuery的角度来讲,Sizzle的出现随之也带来了web上的一些新的局面,在追求效率的同时,即使是这类单种子模式的库也是需要将之分离开来,来设计成能够独立使用,独立维护的引擎。
从选择器的角度来讲,Sizzle这次算法的提升,我初步的结论是它结合了DOM这一特定的数据结构,使其每次的匹配能够更精准,以此获得引擎效率上的提升。
我们可否多想想,在思维的开拓上能给我们留下多少财富。很多问题的解决,在换一种新的思维方式后,是不是常常会有柳暗花明的感觉呢。
相关参考:W3C css selector:CSS1,CSS2,CSS3
CSS Support History -Brian Wilson
CSS Selectors and Pseudo Selectors and browser support – kimblim.dk
Javascript CSS Selector Engine Timeline – Paul Irish