jQuery选择器源码解读(五):tokenize的解析过程(3)


tokens.push({ 
    value : matched, 
    type : type, 
    matches : match 

创建一个新对象{ value: "class", type:"CLASS", matches: ["class"] },并将该对象压入tokens数组。

复制代码 代码如下:


soFar = soFar.slice(matched.length); 

soFar变量删除class,此时,soFar = ":contain('span')):eq(3"
第三次for循环:从Expr.filter中取出第三个元素"ATTR"赋给type变量,执行循环体代码。
同样,由于当前剩余选择器不是属性选择器,故结束本次循环。

第四次for循环:从Expr.filter中取出第四个元素"CHILD"赋给type变量,执行循环体代码。
同样,由于当前剩余选择器不是CHILD选择器,故结束本次循环。

第五次for循环:从Expr.filter中取出第五个元素"PSEUDO"赋给type变量,执行循环体代码。

复制代码 代码如下:


if ((match = matchExpr[type].exec(soFar)) 
        && (!preFilters[type] || (match = preFilters[type] 
                (match)))) { 

match = matchExpr[type].exec(soFar)的执行结果如下:
[":contain('span')", "contain", "'span'", "'", "span", undefined, undefined, undefined, undefined, undefined, undefined]

由于存在preFilters["PSEUDO"],故执行其后的代码:

复制代码 代码如下:


match = preFilters[type](match)

preFilters["PSEUDO"]代码如上所示,此处不再列举。

复制代码 代码如下:


"PSEUDO" : function(match) { 
    var excess, unquoted = !match[5] && match[2]; 
 
    if (matchExpr["CHILD"].test(match[0])) { 
        return null; 
    } 
 
    if (match[3] && match[4] !== undefined) { 
        match[2] = match[4]; 
    } else if (unquoted 
            && rpseudo.test(unquoted) 
            && (excess = tokenize(unquoted, true)) 
            && (excess = unquoted.indexOf(")", unquoted.length 
                    - excess) 
                    - unquoted.length)) { 
 
        match[0] = match[0].slice(0, excess); 
        match[2] = unquoted.slice(0, excess); 
    } 
 
    return match.slice(0, 3); 

传入的match参数等于:
[":contain('span')", "contain", "'span'", "'", "span", undefined, undefined, undefined, undefined, undefined, undefined]

复制代码 代码如下:


unquoted = !match[5] && match[2]; 

unquoted = "span"

复制代码 代码如下:


 if (matchExpr["CHILD"].test(match[0])) {
  return null;
 }

由于":contain('span')"不匹配matchExpr["CHILD"]正则表达式,故不执行内部语句体。

复制代码 代码如下:


 if (match[3] && match[4] !== undefined) {
  match[2] = match[4];
 }

由于match[3] = "'",match[4] ="span",故执行if内部语句体,将"span"赋予match[2]

复制代码 代码如下:


return match.slice(0, 3); 

返回match前三个元素的副本
此时回到tokenize方法的for循环内继续执行,此时各变量值如下:

match = [":contain('span')", "contain", "span"]

soFar = ":contain('span')):eq(3"

复制代码 代码如下:


matched = match.shift(); 

将":contain('span')"移除match数组,并赋予matched变量

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgjpwf.html