jQuery選擇器源碼解讀(六):Sizzle選擇器匹配邏輯分析
近期看了一些網上關于Sizzle的分析文章,就匹配次序往往就說使用了從右到左的逆向匹配法,但是具體如何并沒有詳細介紹,或者就像我之前的幾篇文章一樣,就代碼一行一行做詳細介紹,但缺乏整體概念,這里就jQuery-1.10.2版本的Sizzle的匹配邏輯(預編譯結果)做一整體說明,這里就不談過多的細節(jié)了。
Sizzle的匹配過程采用的是以從右到左的逆向匹配法為基礎的改進版本,因為HTML的搜索畢竟和文本匹配有差異,它有自己獨特的一面,所以,需要針對HTML的搜索進行優(yōu)化。在此先申明一點,下面所說的關系選擇器是指W3C中的Combinator選擇器,因本人覺得用關系選擇器這個名字要比其它更加貼近實際意義,故用此命名。
1、簡單介紹一下Sizzle編譯執(zhí)行的兩個主要函數(shù):
a) matcherFromTokens——針對一個塊選擇器生成執(zhí)行函數(shù),所謂塊選擇器就是不包含逗號分隔的選擇器字符串。
b) matcherFromGroupMatchers——將不同的塊選擇器生成的最終執(zhí)行函數(shù),該函數(shù)還負責將最終結果過濾掉重復對象。
2、matcherFromTokens函數(shù)針對不同類型的選擇器產生不同的執(zhí)行函數(shù)。若包含偽類,則返回setMatcher,否則返回的是elementMatcher,代碼通過鑒別matcher是否包含expando屬性來區(qū)別setMatcher和elementMatcher:
a) 針對非偽類且非關系選擇器,直接從左到右依次生成執(zhí)行函數(shù),各函數(shù)作為同一個matchers數(shù)組的不同元素存在。
b) 針對關系選擇器,將會把之前生成的matchers壓入一個新的matchers數(shù)組中。
c) 針對偽類選擇器,將通過setMatcher函數(shù)生成一個執(zhí)行函數(shù),調用setMatcher時,依次傳入6個參數(shù),分別是preFilter, selector, matcher, postFilter, postFinder, postSelector。
preFilter是在執(zhí)行setMatcher函數(shù)之前已生成的matchers數(shù)組經elementMatcher函數(shù)加工過的最終函數(shù),elementMatcher(matchers)將返回一個從后向前依次執(zhí)行每一個matchers元素函數(shù)的新函數(shù);。
selector是matchers對應的選擇器字符串;
matcher是偽類自身的匹配函數(shù);
postFilter是偽類之后,到第一個偽類或關系符之間的選擇器字符串對應的匹配函數(shù),它是嵌套調用matcherFromTokens函數(shù)的返回結果;
postFinder是postFilter對應選擇器之后的所有選擇器生成的匹配函數(shù),同樣也是通過嵌套調用matcherFromTokens函數(shù)的返回結果;
postSelector是postFinder對應的選擇器字符串。
d) 若選擇器字符串中沒有偽類,那么,將返回elementMatcher(matchers)生成的最終匹配函數(shù)。
從上面的介紹可以看出,生成的執(zhí)行函數(shù)之間存在著嵌套關系,簡單的講就是setMatcher包含matchers,關系選擇器匹配函數(shù)包含非偽類且非關系選擇器匹配函數(shù)。
3、執(zhí)行過程的介紹:
a) 執(zhí)行塊選擇器的執(zhí)行函數(shù):
針對elementMatcher,從外到里從后到前依次執(zhí)行,即從最外層數(shù)組到最里層數(shù)組依次執(zhí)行,同一個數(shù)組中,從最后一個元素到第一個元素依次執(zhí)行。
針對setMatcher,先依據preFilter和selector獲得匹配結果;然后執(zhí)行matcher函數(shù)獲取匹配結果;之后,執(zhí)行postFilter函數(shù),最后,依據postFinder和postSelector獲取匹配結果。
c) 依次執(zhí)行每個塊選擇器的執(zhí)行函數(shù)后,過濾掉重復數(shù)據,并返回結果。
看了上述大致過程,再去看各方法的詳細介紹應該比較容易理解了,當然在這里沒有談到一些細節(jié),例如初始結果集(seed)的生成及由此帶來的函數(shù)執(zhí)行邏輯細節(jié)上的差異等。
相關文章
jquery實現(xiàn)點擊label的同時觸發(fā)文本框點擊事件的方法
這篇文章主要介紹了jquery實現(xiàn)點擊label的同時觸發(fā)文本框點擊事件的方法,涉及jQuery鼠標事件及頁面元素操作的技巧,需要的朋友可以參考下2015-06-06
jQuery使用slideUp方法實現(xiàn)控制元素緩慢收起
這篇文章主要介紹了jQuery使用slideUp方法實現(xiàn)控制元素緩慢收起的功能,實例分析了jQuery中slideUp方法的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-03-03
Jquery+WebService 校驗賬號是否已被注冊的代碼
在Javascirpt代碼中,調用Jquery的方法$.Ajax(function)實現(xiàn)Ajax,傳遞賬號信息給Web服務,Web服務再調用數(shù)據庫操作類查詢數(shù)據庫,并返回數(shù)據給前臺頁面。2010-07-07

