tokens.push({
value : matched,
type : type,
matches : match
}
创建一个新对象{ value:
":contain('span')", type:"PSEUDO", matches: ["contain", "span"] },并将该对象压入tokens数组。
复制代码 代码如下:
soFar = soFar.slice(matched.length);
soFar变量删除":contain('span')",此时,soFar="):eq(3)",之后,直至for循环结束,且再次执行while循环,也没有一个有效选择器,故退出while循环。
复制代码 代码如下:
return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
tokenCache(selector, groups).slice(0);
由于此时parseOnly = true,故返回此时soFar的长度6,继续执行preFilters["PSEUDO"]的代码
复制代码 代码如下:
else if (unquoted
&& rpseudo.test(unquoted)
&& (excess = tokenize(unquoted, true))
&& (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)
将6赋予excess变量,然后由代码
复制代码 代码如下:
excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length
计算出:not选择器结束位置(即右括号位置)22
复制代码 代码如下:
match[0] = match[0].slice(0, excess);
match[2] = unquoted.slice(0, excess);
分别计算出完整的:not选择器字符串(match[0])和其括号内的字符串(match[2]),分别等于:
match[0] = ":not(.class:contain('span'))"
match[2] = ".class:contain('span')"
复制代码 代码如下:
return match.slice(0, 3);
返回match中前三个元素的副本。
回到tokenize函数,此时match = [":not(.class:contain('span'))", "not", ".class:contain('span')"]
复制代码 代码如下:
matched = match.shift();
移除match中的第一个元素":not(.class:contain('span'))",并将该元素赋予matched变量,此时matched="":not(.class:contain('span'))"",
match = ["not", ".class:contain('span')"]
复制代码 代码如下:
tokens.push({
value : matched,
type : type,
matches : match
}
创建一个新对象{ value: ":not(.class:contain('span'))"", type:"PSEUDO", matches: ["not", ".class:contain('span')"] },并将该对象压入tokens数组。此时tokens共有两个元素分别是div和not选择器。
复制代码 代码如下:
soFar = soFar.slice(matched.length);
soFar变量删除":not(.class:contain('span'))",此时,soFar=":eq(3)",结束本次for循环后,再次回到while循环,同样方式,获取tokens的第三个元素eq选择器,过程与not一致,这里就不再细讲了。最后的groups的结果如下:
group[0][0] = {value: "div", type: "TAG", matches: ["div"] }
group[0][1] = {value: ":not(.class:contain('span'))", type: "PSEUDO", matches: ["not", ".class:contain('span')"] }
group[0][2] = {value: ":eq(3)", type: "PSEUDO", matches: ["eq", "3"] }
复制代码 代码如下:
return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
tokenCache(selector, groups).slice(0);
由于parseOnly = undefined,所以执行tokenCache(selector, groups).slice(0),该语句将groups压入缓存,并返回其副本。
由此,完成了所有的解析,或许有人会问,这里第二个元素并没有解析出来呀,是的,这个需要在实际运行中再次解析。当然,这里若可以将刚才解析."class:contain('span')):eq(3"时,将有效选择器的结果保存到缓存内,那么就可以避免再次解析,提高执行速度。但这也仅仅提高了当前这次运行速度。因为在执行过程中,对".class:contain('span')"再次提交解析时,会存入缓存。
至此,整个执行过程已经全部结束。
您可能感兴趣的文章: