jquery源码学习(二)sizzle部分 【转】

一,sizzle的基本原理

sizzle是jquery选择器引擎模块的名称,早在1.3版本就独立出来,并且被许多其他的js库当做默认的选择器引擎。
首先,sizzle最大的特点就是快。那么为什么sizzle当时其他引擎都快了,因为当时其他的引擎都是按照从左到右逐个匹配的方式来进行查找的,而sizzle刚好相反是从右到左找的。

举个简单的例子 “.a .b .c”来说明为什么sizzle比较快。这个例子如果按照从左到右的顺序查找,很明显需要三次遍历过程才能结束,即先在document中查找.a,然后再结果中查找.b,再在.b的结果中查找.c。
采用这种方式,其时间复杂度是 a*b*c,其实也就是时间复杂度 O(n3)。注意这里的O(n3)只算对dom的遍历查找,因为现对于对PO的操作这个是特别耗时。
下面再看看sizzle是怎么做的,sizzle是从右到左查找,也就是直接在页面中查找.c,这时会得到一个候选结果集seed,然后对seed的每一个结果把parents不符合.a .b的结果剔除掉,就是最终结果。这个过程实际上只对dom进行了一次遍历查找,剩下的过滤操作是沿着parent指针直接查找非常快速。可以认为这是一个时间复杂度O(n)的算法。
所以,可以看出只需要遍历查找一次dom的sizzle在理论上是有明显的速度优势的,当然实践检验也证明了这点。

二,sizzle的实现

1,首先调用Sizzle(selector, context)方法

此方法做的事: 
     1.1 先设置上下文context,然后调用rquickExpr正则式来判断是不是简单的id/class/tag选择器,如果是则直接调用相应的方法就可以得到结果
     1.2 如果不是简单的选择器,则查看是否支持qsa(即querySelectorAll)方法,如果支持则调用querySelectorAll方法来取结果
     1.3 否则,没有任何捷径,则调用 select(selector, context, results, seed)

2, 调用select(selector, context, results, seed) 方法

2.1 首先调用tokenize(selector)方法把selector分解成单个token
     2.2 如果没有种子seed,那么2.3
     2.3 如果分解出来的token只有一组,那么根据tokens从右往左查找seed,比如选择器是".a .b .c",那么先找到所有的.c元素存到候选集seed里,以后所要做的就是过滤掉seed中不符合的元素即可
     2.4 最后调用 compile(selector, match)(seed, context)剔除seed中不符合条件的元素即可

3, 调用 compile 方法

此方法返回一个函数,这个函数被调用之后:
     3.1,对每一个seed中得元素调用matcher逐个过滤,把符合的结果存到results数组中。matcher方法的实现,参见4

4,matcher方法

matcher的作用是,对候选集seed进行过滤,matcher的实现过程就是对一个元素不断向上找parentNode并且判断parentNode是不是满足条件,不满足条件的就返回false。

大体原理就是这样,具体到更下面的实现细节 暂时不想逐个看,如果本系列全部更新完之后有空闲时间 就再来完善这一章。 ^_^

jquery源码学习(二)sizzle部分 【转】,布布扣,bubuko.com

时间: 2024-08-01 22:44:12

jquery源码学习(二)sizzle部分 【转】的相关文章

jQuery源码学习(二)

回调对象Callbacks 回调对象Callbacks就是用来管理回调函数队列的. 参数说明 它提供几个便捷的处理参数 - once: 确保这个回调列表只执行一次 - memory: 保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 - unique: 确保一次只能添加一个回调(所以在列表中没有重复的回调). - stopOnFalse: 当一个回调返回false 时中断调用 once和stopOnFalse作用于fire memory和unique作用于add once在源码

菜鸟的jQuery源码学习笔记(二)

jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: 1 jQuery.fn = jQuery.prototype = { 2 //成员变量和方法 3 } 这里给原型对象起了一个别名叫做jQuery.fn.要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的.如果你在控制台敲$().fn的话输出的结果会是undefined.接下来看看原型对象里面有些

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

jQuery源码学习笔记:总体架构

1.1.自调用匿名函数: (function( window, undefined ) { // jquery code })(window); 这是一个自调用匿名函数,第一个括号内是一个匿名函数,第二个括号立即执行,传参是window. 1.为什么有自调用匿名函数? 通过定义匿名函数,创建了一个"私有"空间,jQuery必须保证创建的变量不能和导入它的程序发生冲突. 2.为什么传入window? 传入window使得window由全局变量变成局部变量,jQuery访问window时,

jQuery源码学习笔记五 六 七 八 转

jQuery源码学习笔记五 六 七 八 转 Js代码   <p>在正式深入jQuery的核心功能选择器之前,还有一些方法,基本都是数组方法,用于遴选更具体的需求,如获得某个元素的所有祖选元素啦,等等.接着是其缓存机制data.</p> <pre class="brush:javascript;gutter:false;toolbar:false"> //@author  司徒正美|なさみ|cheng http://www.cnblogs.com/ru

jquery源码学习(一)core部分

这一部分是jquery的核心 jquery的构造器 jquery的核心工具函数 构造器 jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQu

十五.jQuery源码解析之Sizzle总体结构.htm

Sizzle是一款纯javascript实现的css选择器引擎,它具有完全独立,无库依赖;小;易于扩展和兼容性好等特点. W3C Selectors API规范定义了方法querySelector()和querySelectorAll(),但是IE6,7不支持这两个方法. 在Sizzele内部,如果浏览器支持方法querySelectorAll(),则调用该方法查找元素,如果不支持,则模拟该方法的行为. Sizzle支持几乎所有的css3选择器,并且会按照文档位置返回结果. 上面截取的只是Siz

十六.jQuery源码解析之Sizzle设计思路.htm

为了便于后面的叙述,需要了解一些相关术语和约定. 并列选择器表达式:"div,p,a"====>div,p,a是并列的. 块表达式:"div>p"中的div和p就是两个块. 块表达式的类型:共8种.id,class,name,attr,tag,child,pos,pseudo(伪类表达式) 块间的关系符:共4种.">":父子关系,"+":紧挨着的兄弟关系,"~":后面的所有兄弟关系,&qu

jquery源码学习-构造函数(2)

最近几天一直在研究jquery源码,由于水平太低看得昏头转向.本来理解的也不是很深刻,下面就用自己的想法来说下jquery是如何定义构造函数初始化的.如果有什么不对的地方,希望个位高手指出.  一般写构造函数如下 function Aaa(){} Aaa.prototype.init = function(){}; Aaa.prototype.css = function(){}; var a1 = new Aaa(); a1.init(); //初始化 a1.css(); jQuery写法如下