天天看點

[原創] jQuery源碼分析-04 選擇器-Sizzle-設計思路

作者:nuysoft/高雲 QQ:47214707 Email:[email protected] 
聲明:本文為原創文章,如需轉載,請注明來源并保留原文連結      
讓我們把工作原理講的更簡單一些,先不講從右向左也不講接口,先來分析下如果要執行一段選擇器表達式,或者說設計一個簡版選擇器引擎,直覺上需要做些什麼工作: 
以div > p為例來模拟這個過程,找div元素下的p元素: 

1. 首先要能正确的将獨立的塊表達式從選擇器表達式中分割出來,這是必須的,否則沒法找div元素或p元素 

2. 然後要能正确的執行塊表達式,無論是left>right或right>left,首先要能找到div元素或p元素 
塊表達式可能不僅僅是簡單的id/name/tag/class,也可能是它們之間的組合,甚至是與僞類的組合 
比如div.red,查找具有指定.red的div,怎麼實作這個過程呢? 
可以先找div數組,再在div數組上過濾.red;或者也可以先找*.red數組,再在*.red數組上找div 
不管哪種方式,上邊的過程都可以分解為:一個簡單查找器和一個對查找結果過濾的過濾器 

3. 單個塊表達式搞定了,最後來處理塊表達式之間的關系,DOM元素之間關系不外乎四種:父子,祖先,兄長,兄弟 
就是找父親或找兒子,找祖宗或找後代,找哥哥姐姐或找弟弟妹妹,關系不複雜,都有原生API支援
隻要把2~3重複執行就可以完成(我感覺我的神經好粗大),選擇器引擎的大緻思路就是如此。

把上述過程與Sizzle對應着了解: 
1. 分割器 chunker正則 
2. 塊查找 Sizzle.find( expr, context, isXML ) 
   塊内過濾 Sizzle.filter( expr, set, inplace, not ) 
3. 塊間關系過濾 Expr.relative 
這三個接口正是Sizzle實作的核心API。 
  
當然上邊的分析有事後諸葛亮的嫌疑,畢竟我已經看過Sizzle源碼了, 但是當我試着用上邊的過程來了解Sizzle的工作原理時,頓時豁然開朗,希望有所啟發。      

繼續閱讀