jQuery 从 1.3 版本开始,使用了新的选择器引擎 Sizzle(官方网址 http://sizzlejs.com) 。Sizzle 是 jQuery 作者 John Resig 开发的 DOM 选择器引擎 (Dom Selector Engine),速度号称业界第一。而且它有一个重要的特点就是 Sizzle 是完全独立于 jQuery 的,如果用户不想用 jQuery ,还可以只用 Sizzle 。
Sizzle 选择器引擎目前成为 jQuery 框架默认的选择器引擎,相比原来的 jQuery 引擎,速度有很大的提升,如图 2.3 所示的各种选择器执行效率的对比。
在解析 jQuery 选择器引擎 Sizzle 之前,我们不妨回顾一下 CSS 的选择器 (CSS selector) 。CSS选择器可以分为三种基本类型:ID选择器 (#id)、Class选择器(.class)和类型(type)选择器(p)。
另外,CSS还支持高级选择器,如属性选择器 (attribute)、伪类或伪对象选择器 (Pseudo Classes) 等。这些都是单一的选择器,可以在应用中把它们组合起来,形成组合选择器,如 div#id,div:last-child。组合型选择器又包括多种关系形式,如包含关系、并列关系、相邻关系和父子关系等。
2.4.2 解析 jQuery 选择器引擎的设计思路尽管 jQuery 选择器引擎 Sizzle 非常复杂,功能也非常强大,但是它们都是建立在 JavaScript 已定义的方法或属性基础上来实现的。这主要包括元素的 getElementsByTagName() 和 getElementById() 方法,以及元素的 childNodes、firstChild、lastChild、nextSibling、parentNode 和 previousSibling 属性。借助这些方法和属性可以直接或间接地选择相匹配的 DOM 元素。
为了方便讲解,我们结合一个选择器进行说明。选择器代码如下所示。
$("div.red");
这是一个复合选择器,一搬读者可以这样分析:在DOM文档树中找到 class 属性等于 "red" 的 div 元素。即一步到位,直接从DOM文档树中选择所需要的元素。实际上,如果根据选择器引擎的工作方式,可以把这个字符串拆分成两步走。
- 第一步,根据 document.getElementsByTagName() 方法选择文档树中的 div 元素集合。
- 第二步,根据其 class 是否等于 "red" 进行判断,把不等于该值的元素从结果集中去掉。
- 第一步,根据 document.getElementsByTagName() 方法选择文档树中的 div 元素集合。
- 第二步,迭代 div 元素集合,在所有的 div 元素中查找每个 div 元素下的 p 元素。
- 第三步,合并结果。
- 第一步,根据 document.getElementsByTagName() 方法选择文档树中的 p 元素集合。
- 第二步,迭代 p 元素集合,在所有的 p 元素中查找每个 p 元素的父级元素。
- 第三步,检测父级元素。如果不是 div 元素,则遍历上一级元素;如果迭代到文档树的顶层,则排除该 p 元素;如果是 div 元素,则保存该 p 元素。
- 第一类,选择器 (selector) 。即根据给定的选择符,从 DOM 文档树找到相关的元素节点,并存储到结果集中。
- 第二类,过滤器 (filter) 。根据表达式的条件,在结果集中过滤元素。
- 如果它们在 selector 字符串的起始位置,那么它们也可以完成选择功能。例如 $("#id");、$(".class");。
- 如果它们不在起始位置,那么就应该作为筛选器实现。例如 $("div#id"); 、$("div.class"); 。

- <scripttype="text/javascript">
- /*!
- *SizzleCSSSelectorEngine-v0.9.3
- *Copyright2009,TheDojoFoundation
- *ReleasedundertheMIT,BSD,andGPLLicenses.
- *Moreinformation:http://sizzlejs.com/
- */
- //把Sizzle引擎封装在一个独立的空间中
- (function(){
- //定义用于块识别器的正则表达式
- varchunker=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^>+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
- done=0,
- toString=Object.prototype.toString;
- //Sizzle选择器引擎构造器函数
- //参数说明:
- //selector:选择器字符串
- //context:上下文
- //results:结果集
- //seed:种子
- varSizzle=function(selector,context,results,seed){
- //省略的函数体
- };
- //Sizzle匹配函数
- //参数说明:
- //expr:匹配表达式
- //set:条件设置选项
- Sizzle.matches=function(expr,set){
- returnSizzle(expr,null,null,set);
- };
- //Sizzle查询函数
- //参数说明:
- //expr:查询表达式
- //context:上下文
- //isXML:检测函数
- Sizzle.find=function(expr,context,isXML){
- //省略的函数体
- };
- //Sizzle过滤函数
- //参数说明:
- //expr:过滤表达式
- //set:条件设置选项
- //inplace:包含项
- //not:排除项
- Sizzle.filter=function(expr,set,inplace,not){
- //省略的函数体
- };
- //Sizzle表达式对象
- //列举所用的各种匹配表达式
- varExpr=Sizzle.selectors={
- //省略成员属性
- };
- //省略其他辅助性工具函数和逻辑代码暴露的接口
- jQuery.find=Sizzle;
- jQuery.filter=Sizzle.filter;
- jQuery.expr=Sizzle.selectors;
- jQuery.expr[":"]=jQuery.expr.filters;
- //定义的公共函数
- Sizzle.selectors.filters.hidden=function(elem){};
- Sizzle.selectors.filters.visible=function(elem){};
- Sizzle.selectors.filters.animated=function(elem){};
- jQuery.multiFilter=function(expr,elems,not){};
- jQuery.dir=function(elem,dir){};
- jQuery.nth=function(cur,result,dir,elem){};
- jQuery.sibling=function(n,elem){};
- return;
- window.Sizzle=Sizzle;
- })();
-
关注打赏


微信扫码登录