Sizzle过滤器主要包含两部分:第一部分是过滤函数(jQuery.filter()),在该函数中将对需要过滤的表达式及其对应的表达式处理函数执行分析,并返回过滤后的jQuery对象;第二部分就是过滤表达式对象(Expr = Sizzle.selectors),该对象包含了所有表达式处理的方法和匹配的正则表达式。
Sizzle选择器先初步分析参数字符串,找出基本特征字符串,并根据这些特征字符在Expr对象中调用对应的正则表达式,然后进一步分析选择符字符串,同时根据进一步分解出来的特殊字符,在Expr对象中匹配到对应的选择器函数,最后根据这个选择器函数的返回值是否为true,决定是否保留当前过滤的元素。被保留的元素就是筛选元素,它将被推进jQuery对象集合中。
jQuery.filter()函数完成分析属性([])、Pseudo(:)、Class (.)和ID(#)的筛选功能,从给定的集合中筛选出满足上面四种筛选表达式的集合。针对find()方法,jQuery.filter()函数的完成并不表明整个选择符的分析完成了,如果单独使用这个函数,表达式中就不应该含有查找的选择器表达式。筛选是根据[、:、#和.这四个符号来作为筛选器的分隔符的。Class筛选器通过classFilter来完成,它还把Pseudo中的:not、:nth-child单独从Pseudo类中提出来处理。对于[的属性筛选器,实现起来也很简单。除去这些,它还调用jQuery.expr[m[1]];来处理Pseudo类。
Sizzle过滤器的实现代码如下所示。
广州网站建设,网站建设,广州网页设计,广州网站设计
- Sizzle.filter = function(expr, set, inplace, not){
- var old = expr, result = [], curLoop = set, match, anyFound,
- isXMLFilter = set && set[0] && isXML(set[0]);
- while ( expr && set.length ) {
- //Expr.filter包含元素[CHILD,PSEUDO,ID,TAG,CLASS, ATTR,POS],元素类型是Function
- //match: {
- // ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
- // CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
- // NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
- // ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+ )\s*(?:(\S?=)\s*(['"]*) (.*?)\3|)\s*\]/,
- // TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
- // CHILD: /:(only|nth|last|first)-child(?:\( (even|odd|[\dn+-]*)\))?/,
- // POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
- // PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+ )(?:\((['"]*)((?:\([^\])+\)|[^\2\ (\)]*)+)\2\))?/
- //}
- for ( var type in Expr.filter ) {
- //这里先判断下过滤器是不是符合jQuery选择器的语法
- //把正则匹配的结果赋值给match变量
- //当type为PSEUDO和POS时,进入该代码块
- if ( (match = Expr.match[ type ].exec( expr )) != null ) {
- var filter = Expr.filter[ type ], found, item;
- anyFound = false;
- if ( curLoop == result ) {
- result = [];
- }
- //Expr.preFilter和Expr.filter定义方法类似,只是元素的方法不一样
- //主要功能就是做过滤之前的过滤器处理,例如:
- //ID: function(match){
- // return match[1].replace(/\\/g, "");
- //},
- //就是去掉\,
- //TAG: function(match, curLoop){
- // for ( var i = 0; !curLoop[i]; i++ ){}
- // return isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
- //},
- //判断标签是不是XML对象,如果不是返回标签大写
- if ( Expr.preFilter[ type ] ) {
- //进一步处理正则匹配的结果,由于js没有方法重载的概念,
- //虽然有些元素可能没有5个参数,js编译器会自动忽略,而不会出错
- //例如,在C语言中会报错,js不会
- //用到5个参数的只有CLASS过滤和PSEUDO
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
- if ( !match ) {
- anyFound = found = true;
- } else if ( match === true ) {
- continue;
- }
- }
- //如果存在匹配
- if ( match ) {
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- var pass = not ^ !!found;
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
- } else {
- curLoop[i] = false;
- }
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
- //如果匹配到元素
- if ( found !== undefined ) {
- //如果没有指定上下文
- if ( !inplace ) {
- curLoop = result;
- }
- exprexpr = expr.replace( Expr.match[ type ], "" ); //清除空格
- //如果不匹配,则返回空数组
- if ( !anyFound ) {
- return [];
- }
- break;
- }
- }
- }
- //处理不正确的表达式
- if ( expr == old ) {
- if ( anyFound == null ) {
- throw "Syntax error, unrecognized expression: " + expr;
- } else {
- break;
- }
- }
- //把表达式传递给old存储
- old = expr;
- }
- //返回过滤的集合
- return curLoop;
- };
广州网站建设,网站建设,广州网页设计,广州网站设计



