jQuery技术内幕:深入解析jQuery架构设计与实现原理. 3.6 Sizzle.find( expr, context, isXML )

3.6 Sizzle.find( expr, context, isXML )

方法Sizzle.find( expr, context, isXML )负责查找与块表达式匹配的元素集合。该方法会按照表达式类型数组Sizzle.selectors.order规定的查找顺序(ID、CLASS、NAME、TAG)逐个尝试查找,如果未找到,则查找上下文的所有后代元素(*)。

 

图3-3 Sizzle( selector, context, results, seed )的执行过程

 

 

方法Sizzle.find( expr, context, isXML )执行的5个关键步骤如下:

1)先用正则集合Sizzle.selectors.leftMatch中的正则确定表达式类型。

2)然后调用查找函数集Sizzle.selectors.find中对应类型的查找函数,查找匹配的元素集合。

3)然后删除块表达式中已查找过的部分。

4)如果没有找到对应类型的查找函数,则读取上下文的所有后代元素。

5)最后返回格式为{set:候选集, expr:块表达式剩余部分}的对象。

下面来看看该方法的源码实现。

1.?定义Sizzle.find( expr, context, isXML )

相关代码如下所示:

4051 Sizzle.find = function( expr, context, isXML ) {

第4051行:定义方法Sizzle.find( expr, context, isXML ),它接受3个参数:

参数expr:块表达式。

参数context:DOM元素或文档对象,作为查找时的上下文。

参数isXML:布尔值,指示是否运行在一个XML文档中。

2.?遍历表达式类型数组Sizzle.selectors.order

相关代码如下所示:

4052     var set, i, len, match, type, left;

4053

4054     if ( !expr ) {

4055         return [];

4056     }

4057

4058     for ( i = 0, len = Expr.order.length; i < len; i++ ) {

4059         type = Expr.order[i];

4060        

第4054~4056行:如果块表达式expr是空字符串,则直接返回空数组[]。

第4058行:表达式类型数组Sizzle.selectors.order中定义了查找单个块表达式时的顺序,依次是ID、CLASS、NAME、TAG,其中,CLASS需要浏览器支持方法getElements

ByClassName()。关于Sizzle.selectors.order的具体说明请参见3.9.1节。

(1)确定块表达式类型Sizzle.selectors.leftMatch[ type ]

相关代码如下所示:

4061         if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {

4062             left = match[1];

4063             match.splice( 1, 1 );

4064

第4061行:检查每个表达式类型type在Sizzle.selectors.leftMatch中对应的正则是否匹配块表达式expr,如果匹配,则可以确定块表达式的类型。

第4062~4063行:对象Sizzle.selectors.leftMatch中存放了表达式类型和正则的映射,正则可以用于确定块表达式的类型,并解析其中的参数。它是基于对象Sizzle.selectors.match初始化的,具体请参见3.9.2节。

(2)查找匹配元素Sizzle.selectors.find[ type ]

相关代码如下所示:

4065             if ( left.substr( left.length - 1 ) !== "\\" ) {

4066                 match[1] = (match[1] || "").replace( rBackslash, "" );

4067                 set = Expr.find[ type ]( match, context, isXML );

4068

第4065行:如果匹配正则的内容以反斜杠"\\"开头,表示反斜杠"\\"之后的字符被转义了,不是期望的类型,这时会认为类型匹配失败。

第4066行:过滤其中的反斜杠,以支持将某些特殊字符(例如,“#”、“.”、“[”)作为普通字符使用。举个例子,假设某个input元素的属性id是"a.b",则对应的选择器表达式应该写作$("#a\\.b"),这里替换掉了反斜杠,又会变回"a.b",因此仍然可以通过执行document.getElementsById("a.b")查找到input元素。

第4067行:调用表达式类型type在查找函数集Sizzle.selectors.find中对应的查找函数,查找匹配的元素集合。Sizzle.selectors.find中定义了ID、CLASS、NAME、TAG所对应的查找函数,具体请参见3.9.3节。

(3)删除块表达式中已查找过的部分

相关代码如下所示:

4069                 if ( set != null ) {

4070                     expr = expr.replace( Expr.match[ type ], "" );

4071                     break;

4072                 }

4073             }

4074         }

4075     }

4076

第4069~4072行:如果set不是null和undefined,表示对应的查找函数执行了查找操作,则不管有没有找到匹配元素,都将块表达式expr中已查找过的部分删除,并结束方法Sizzle.find( expr, context, isXML )的查找过程。

第4070行:用对象Sizzle.selectors.match中对应的正则来匹配已查找过的部分,具体请参见3.9.2节。

3.?如果没有找到对应类型的查找函数,则读取上下文的所有后代元素

相关代码如下所示:

4077     if ( !set ) {

4078         set = typeof context.getElementsByTagName !== "undefined" ?

4079             context.getElementsByTagName( "*" ) :

4080             [];

4081     }

4082

第4077~4081行:如果set是null或undefined,(大多数情况下)表示没有在Sizzle.selectors.find中找到对应的查找函数,例如,$(":input")会读取上下文的所有后代元素作为候选集。

4.?返回{ set:候选集, expr:块表达式剩余部分}

相关代码如下所示:

4083     return { set: set, expr: expr };

4084 };

方法Sizzle.find( expr, context, isXML )的执行过程可总结为图3-5。

 

图3-5 Sizzle.find( expr, context, isXML )的执行过程

上一篇:通过存储过程进行分页查询的SQL示例


下一篇:bill