当选择表达式不符合高速匹配(id,tag,class)和原生QSA不可用或返回错误时,将调用select(selector, context, results, seed)方法,此方法迭代DOM选择、过滤元素,
在DOM树很大的时候为了保证效率,应该保证html设计的合理,尽量使用可高速匹配(id,tag,class)的表达式,其次是QSA支持的选择器,尽量不要使用jquery扩展的selector和嵌套selector ,然后是尽量不要使用位置伪类(它是从左向右查找,须要多次循环内套循环遍历),还有要尽量缩小context 。 能够多次反复利用同一选择器,它并不会每次都去筛选DOM(JQuery会对其结果进行缓存,当然假设选择元素太多,不会对其缓存).
select(selector, context, results, seed)方法分为以下几个关键步骤
1 调用tokenize(selector)切割selector
tokenize(selector,parseOnly)方法的运行步骤
1.1定义变量 matched匹配元素、match匹配捕获组、tokens存放selector的各个部分和其类型、sofar存放当前selector
(被上次处理切割后的selector)、groups存放每一个selector的tokens、preFilter就是Expr.preFilter
1.2首先查看tokenCache缓存中此selector是否已经被切割过,假设有返回缓存的值,否则继续向下运行.
1.3定义groups数组,它是一个二维数组,每一个selector('div, div span'注意此表达式有两个selector)相应一个groups元素
1.4切割关系符(后代,>,+,~),将匹配的关系符包含前后空白和去除空白的关系符放入tokens.将soFar设置为剩下的selector
1.5匹配selector的类型(ATTR,CHILD,CLASS,ID,PSEUDO,TAG),将匹配的selector部分和其类型放入tokens,将soFar设置为剩下的selector
1.6没有匹配的元素则退出循环,防止soFar不变造成的死循环
1.7假设传入的parseOnly表明仅仅转换返回soFar的长度,否则将其groups放入tokenCache缓存中并返回groups(假设soFar还有说明selector有误,抛出错误)
2 假设selector仅仅有一个
2.1假设selector第一切割是id选择器,将其设置为查找上下文,假设查找不到id的元素,则高速返回.
2.2假设是须要上下文的选择器,从右向左查找.
2.3依据切割的片段类型,调用对应Expr.find方法,将返回结果作为seed
3 调用compile(selector, match)(seed, context)剔除seed中不符合条件的元素