當選擇表達式不符合快速比對(id,tag,class)和原生QSA不可用或傳回錯誤時,将調用select(selector, context, results, seed)方法,此方法疊代DOM選擇、過濾元素,
在DOM樹非常大的時候為了保證效率,應該保證html設計的合理,盡量使用可快速比對(id,tag,class)的表達式,其次是QSA支援的選擇器,盡量不要使用jquery擴充的selector和嵌套selector,然後是盡量不要使用位置僞類(它是從左向右查找,需要多次循環内套循環周遊),還有要盡量縮小context.
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中不符合條件的元素