JS框架設計讀書筆記之 選擇器引擎02

2022-02-09 08:34:14 字數 1928 閱讀 9829

以sizzle的主函式宣告為例,來說明引擎的相關概念。

function

sizzle(selector, context, results, seed)

種子集seed:如果css選擇器非常複雜,需要分幾步來得到結果,那麼第一次得到的元素集合就叫種子集。sizzle引擎的解析基本上是由右到左,種子集中的一部分就是我們最後得到的元素。如果引擎是由左到右,那麼就只是依次查詢兄弟與子節點。

結果集results:選擇器引擎最終返回的元素集合,約定要與queryselectorall得到的一致,沒有重複元素且要與dom樹上出現的順序一致。

過濾集:選取一組元素後,之後每一步驟要處理的元素集合都可以稱為過濾集。比如p.aaa,假設瀏覽器不支援queryselectorall,那麼就只能通過getelementbyclassname獲取到.aaa,然後迴圈判斷tagname === 'p'進行過濾。若不支援classname,只能通過getelementsbytagname得到種子集,然後通過classname進行過濾。顯示,前面的方法比較快,因為class肯定少;同理,如果是id的話就更簡單了,因為id只有乙個,所以查詢更快。sizzle中,若不支援高階查詢queryselectorall,會以id、class、tag的順序查詢。

選擇器群組:乙個選擇符被併聯選擇器','劃分成多個組。

選擇器組:選擇器群組被關係選擇器劃分的第乙個分組。

isxml:xml與html文件有很大的差異,沒有classname、getelementbyid,並且nodename區分大小寫。

作者給出了乙個相對嚴謹的判斷函式:

function

isxml(doc)

comparedocumentposition:判斷兩個節點的關係,假設a.comparedocumentposition(b),結果如下圖

bits

000000

0元素一致

000001

1節點在不同文件

000010

2節點b在a之前

000100

4節點a在b之前

001000

8節點b包含a

010000

16節點a包含b

100000

32瀏覽器私有使用

有時候,兩個元素關係可能滿足兩個情況,比如a既包含b,又在b之前,會得到20。

sourceindex:舊版本ie不支援comparedocumentposition,於是jquery用另外乙個ie私有方法實現,該方法會根據元素位置從上到下,從左到右依次+1,比如html=0,head=1,body=2...如果元素不在dom,返回-1。

如果選擇器字串過長,包含類、id、tag等,需要乙個正則來進行切割,比如'.class,div a,span'需要切割成['.class',',','div',' ','a',',','body'],然後根據符號依次進行操作,上下文預設指定為document,發現第乙個是類選擇器,就呼叫getelementbyclassname;然後碰到併聯選擇器,將上面的元素放入結果集。接著是標籤選擇器,呼叫getelementbytagname。然後碰到後代選擇器,這裡可以先檢視下乙個選擇器群組是什麼,發現是a標籤,繼續呼叫getelementbytagname,然後對兩個進行過濾。接下來碰到併聯選擇器,重複上面操作。

但是對於:nth-child(n+1)、.td[attr^='abc']這種複雜的選擇符,需要更先進的切割器。

其實,乙個正則切割機已經無法滿足要求,sizzle中應用了大量正則和expr預解析函式進行字串切割,**非常長,sizzle大概從800行-2800行都有涉及,就不貼出來了。

JS框架設計讀書筆記之 選擇器引擎01

選擇符是指css樣式規則最左邊的部分,例如 p id class p.class 等等 總共可以分為四大類 併聯選擇器 逗號 div,span 簡單選擇器 id,class,tag,attr,id class div attr 關係選擇器 div span div span div div div ...

JS框架設計讀書筆記之 動畫

css樣式可分為兩種,一種值接近無限的集合 color,width 一種值只有幾種 display 可以進行計算的樣式,產生了動畫效果。1.動畫的第一步是獲得元素的精確樣式值。2.若要做平移,傳入結束位置 距離 時長 fps。tips fps設定多少合適?除了人的眼睛,還要考慮到顯示器的顯示速度與瀏...

JS框架設計讀書筆記之 節點模組

瀏覽器提供了多種手段建立api,從流行程度依次是document.createelement innerhtml insertadjacenthtml createcontextualfragment。document.createelement 傳入乙個標籤名,返回此型別的元素節點。對於瀏覽器不支...