1 preFilter: {
2 "ATTR": function( match ) {
3 //属性名解码
4 match[1] = match[1].replace( runescape, funescape );
5
6 // Move the given value to match[3] whether quoted or unquoted
7 //属性解码
8 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
9
10 //若判断符为~=,则在属性值两边加上空格
11 if ( match[2] === "~=" ) {
12 match[3] = " " + match[3] + " ";
13 }
14
15 //返回前4个元素
16 return match.slice( 0, 4 );
17 },
18
19 "CHILD": function( match ) {
20 /* matches from matchExpr["CHILD"]
21 1 type (only|nth|...)
22 2 what (child|of-type)
23 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
24 4 xn-component of xn+y argument ([+-]?\d*n|)
25 5 sign of xn-component
26 6 x of xn-component
27 7 sign of y-component
28 8 y of y-component
29 */
30 //match[1]:(only|first|last|nth|nth-last)
31 //match[2]: (child|last-child|of-type|last-of-type)
32 //match[3]: (even|odd)
33 //match[4]、match[5]: an+b中的a,b
34
35 //match[1]变成小写
36 match[1] = match[1].toLowerCase();
37
38 //如果match[1]是"nth"
39 if ( match[1].slice( 0, 3 ) === "nth" ) {
40 // nth-* requires argument
41 //若选择器括号内没有有效参数,则抛出异常
42 if ( !match[3] ) {
43 Sizzle.error( match[0] );
44 }
45
46 // numeric x and y parameters for Expr.filter.CHILD
47 // remember that false/true cast respectively to 0/1
48 /*
49 * 下面先以nth-child()为例介绍一下语法,以便更好的理解下面代码的作用
50 * nth-child允许的几种使用方式如下:
51 * :nth-child(even)
52 * :nth-child(odd)
53 * :nth-child(3n)
54 * :nth-child(+2n+1)
55 * :nth-child(2n-1)
56 * 下面代码中赋值号左侧的match[4]、match[5]用于分别记录括号内n前及n后的数值,包括正负号
57 * 对于:nth-child(even)和:nth-child(odd)来说,match[4]为空,
58 * 所以返回 2 * (match[3] === "even" || match[3] === "odd")的计算结果
59 * 因为在js中true=1,false=0,所以(match[3] === "even" || match[3] === "odd")等于1
60 * 因此,2 * (match[3] === "even" || match[3] === "odd")的计算结果为2
61 *
62 * 等号右侧的“+”的作用是强制类型转换,将之后的字符串转换成数值类型
63 */
64 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
65 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
66
67 // other types prohibit arguments
68 //若非nth起头的其它CHILD类型选择器带有括号说明,则抛出异常
69 } else if ( match[3] ) {
70 Sizzle.error( match[0] );
71 }
72
73 return match;
74 },
75
76 "PSEUDO": function( match ) {
77 var excess,
78 unquoted = !match[6] && match[2];
79
80 if ( matchExpr["CHILD"].test( match[0] ) ) {
81 return null;
82 }
83
84 // Accept quoted arguments as-is
85 if ( match[3] ) {
86 match[2] = match[4] || match[5] || "";
87
88 // Strip excess characters from unquoted arguments
89 } else if ( unquoted && rpseudo.test( unquoted ) &&
90 // Get excess from tokenize (recursively)
91 (excess = tokenize( unquoted, true )) &&
92 // advance to the next closing parenthesis
93 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
94
95 // excess is a negative index
96 match[0] = match[0].slice( 0, excess );
97 match[2] = unquoted.slice( 0, excess );
98 }
99
100 // Return only captures needed by the pseudo filter method (type and argument)
101 return match.slice( 0, 3 );
102 }
103 },