1.简介

jquery从1.3开始,使用了新的选择器–sizzle。效率超过了以前的jquery版本以及目前能见到的其他选择器。以前曾经介绍过:http://www.enjoyphp.com/archives/252

2.sizzle选择器与其他选择器的区别(来自http://www.cssrain.cn/article.asp?id=1315

全文转载如下:

大家都知道 jQuery1.3.x更换了选择器引擎,选择了Sizzle。

那么Sizzle相对于jQuery以前的选择器有什么优势呢? 为什么速度能提升这么高?
最近我在国外的网站看到点内容,大概意思是这样说的。

至于Sizzle代码是怎么实现的,我也没去研究,但我可以给大家讲一个实例,也许这样大家更容易理解。

举个一个选择器来说: $(“div  p”);

每个更换选择器之前,查找步骤如下:
1,先查找页面上所有的div 。
2,循环所有的div,查找每个div下的p 。
3,合并结果 。

采用Sizzle选择器之后,查找步骤如下:
1,先查找页面上所有的p 。
2,循环所有的p,查找每个p的父元素,
1)如果不是div,遍历上一层。
2)如果已经是顶层,排除此p。
3)如果是div,则保存此p元素。

3.源代码分析(摘自http://lwp8407120426.blog.163.com/blog/static/464280752009145364974/

先看下Sizzle是怎么定义的?
var chunker = /((?:((?:([^()]+)|[^()]+)+)|[(?:[[^[]]*]|[^[]]+)+]|\.|[^ >+~,([]+)+|[>+~])(s*,s*)?/g,
done = 0,
toString = Object.prototype.toString;
//上边的正则是不是看的眼花缭乱,我们先分析这个正则是做什么用的?
//先分成两大块
((?:((?:([^()]+)|[^()]+)+)|[(?:[[^[]]*]|[^[]]+)+]|\.|[^ >+~,([]+)+|[>+~])
和(s*,s*)
后边的就不说了,很简单
前边得再进行分,在|的位置分开,|表示或
1.(?:((?:([^()]+)
2.[^()]+)+)
3.[(?:[[^[]]*]
4.[^[]]+)+]|\.
5.[^ >+~,([]+)+ 匹配
6.[>+~] 匹配>+~ 没有子串
//(?:([^()]+)|[^()]+) 这段是验证:last或者是:(xxx)这样的选择器
var Sizzle = function(selector, context, results, seed) {
//确保代码不出错,上下文存在
results = results || [];
context = context || document;
//确保上下文是dom对象
if ( context.nodeType !== 1 && context.nodeType !== 9 )
return [];
//确保选择器是String
if ( !selector || typeof selector !== “string” ) {
return results;
}

var parts = [], m, set, checkSet, check, mode, extra, prune = true;

// Reset the position of the chunker regexp (start from head)
//重置正则得匹配位置
chunker.lastIndex = 0;

while ( (m = chunker.exec(selector)) !== null ) {
parts.push( m[1] );

if ( m[2] ) {
extra = RegExp.rightContext;
break;
}
}
//Expr和Sizzle.selector指向同一个对象,这个选择器和以前的不一样,是在没有用if else进行判断,而是用正则进行处理,具体的代码在定义Expr中。
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:((d*)))?(?=[^-]|$)/,下边的代码就是判断还有没有这样的特殊函数。
if ( parts.length > 1 && Expr.match.POS.exec( selector ) ) {
//relative是函数对象,封装了+>~函数,意思就是typeof Expr.relative[ parts[0] ] ==Function
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
var later = “”, match;

// Position selectors must be done after the filter
// 如果匹配到>+~,处理完之后(过滤上下文),选择器中的该符号去掉,再分析选择器
while ( (match = Expr.match.POS.exec( selector )) ) {
later += match[0];
selector = selector.replace( Expr.match.POS, “” );
}

set = Sizzle.filter( later, Sizzle( /s$/.test(selector) ? selector + “*” : selector, context ) );
} else {
set = Expr.relative[ parts[0] ] ?
[ context ] :
Sizzle( parts.shift(), context );

while ( parts.length ) {
var tmpSet = [];

selector = parts.shift();
if ( Expr.relative[ selector ] )
selector += parts.shift();

for ( var i = 0, l = set.length; i < l; i++ ) {
Sizzle( selector, set[i], tmpSet );
}

set = tmpSet;
}
}
} else {
var ret = seed ?
{ expr: parts.pop(), set: makeArray(seed) } :
Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context );
set = Sizzle.filter( ret.expr, ret.set );

if ( parts.length > 0 ) {
checkSet = makeArray(set);
} else {
prune = false;
}

while ( parts.length ) {
var cur = parts.pop(), pop = cur;

if ( !Expr.relative[ cur ] ) {
cur = “”;
} else {
pop = parts.pop();
}

if ( pop == null ) {
pop = context;
}

Expr.relative[ cur ]( checkSet, pop, isXML(context) );
}
}

if ( !checkSet ) {
checkSet = set;
}

if ( !checkSet ) {
throw “Syntax error, unrecognized expression: ” + (cur || selector);
}

if ( toString.call(checkSet) === “[object Array]” ) {
if ( !prune ) {
results.push.apply( results, checkSet );
} else if ( context.nodeType === 1 ) {
for ( var i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
results.push( set[i] );
}
}
} else {
for ( var i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
results.push( set[i] );
}
}
}
} else {
makeArray( checkSet, results );
}

if ( extra ) {
Sizzle( extra, context, results, seed );
}

return results;
};

4.sizzle的流程图(看不太明白,与大家共勉!)

sizzle选择器流程

  jQuery1.3昨天发布了,今天看了下更新内容,jQuery又强大了很多,官方的性能测试显示:jQuery的性能已经远超于其他JS框架(jQuery自己的测试,可信度未知~~)。

  在本次更新中,最大的亮点就是引入了新选择器引擎Sizzle。Sizzle是jQuery作者John Resig新写的DOM选择器引擎,速度号称业界第一。而且有一个重要的特点就是Sizzle是完全独立于jQuery的,如果你不想用jQuery,可以只用Sizzle。非常好用的,压缩后才3K多点。

  看一个选择器性能对比图:

CSS选择器性能对比

  获得Sizzle的方式:

  1.可以从jQuery1.3的源文件中直接摘取这一部分。

  2.访问Sizzle官方下载http://sizzlejs.com/