jQuery源碼二周目#9 Sizzle

介紹

這是一個CSS選擇器引擎,用于解析像div > p + .aaron[type="checkbox"], #id:first-child這樣的CSS選擇器。

為什么會有Sizzle是因為以前的瀏覽器只有getElementById、getElementsByTagName、getElementsByClassName這三種獲取DOM的手段,是沒法使用上面的css選擇器去獲取DOM元素的。但現(xiàn)在的瀏覽器都提供了document.querySelectorAll接口去獲取DOM,所以Sizzle也就沒用了。既然Sizzle都沒用了為什么還要去學(xué)習(xí)它的源碼,因為它很有意思??偟膩碚f,學(xué)習(xí)了Sizzle的源碼之后雖然不能提升工作能力,但是能夠開闊思路。

解析流程

詞法解析
div > p + .aaron[type="checkbox"], #id:first-child這個選擇器為例來分析解析流程,先是把選擇器分解成一個個單元,單元結(jié)構(gòu)如下

{
    value: '匹配到的字符串',
    type: '對應(yīng)的Token類型',
    matches: '正則匹配到的一個結(jié)構(gòu)'
}

上面的選擇器拆分之后就是

[
  [
    { value: "div", type: "TAG", matches: Array },
    { value: " > ", type: ">" },
    { value: "p", type: "TAG", matches: Array },
    { value: " + ", type: "+" },
    { value: ".aaron", type: "CLASS", matches: Array },
    { value: "[type='checkbox']", type: "CLASS", matches: Array }
  ],
  [
    { value: "#id", type: "ID", matches: Array },
    { value: ":first-child", type: "CHILD", matches: Array }
  ]
]

篩選seed合集
然后是尋找種子合集(seed),從右往左查詢,找到類型為ID、TAG、CLASS中的一種,通過getElementByIdgetElementsByTagName、getElementsByClassName獲取DOM元素,然后重組選擇器。

div > p + .aaron[type="checkbox"]為例來說,從右往左查詢到.aaron,然后通過getElementsByClassName將獲取到的DOM元素并保存在seed中。將{ value: ".aaron", type: "CLASS", matches: Array }從tokens序列中刪除,重組選擇器為div > p + [type="checkbox"]。

預(yù)編譯
遍歷tokens序列然后生成一個個的匹配器

// 遍歷Token序列生成匹配器
function matcherFromTokens(tokens) {
    var
        i,
        token,
        matcher,
        matchers = []
        ;

    for (i = 0; i < tokens.length; i++) {
        token = tokens[i];
        matcher = Expr.filter[token.type].apply(null, token.matches);
        matchers.push(matcher);
    }

    return elementMatcher(matchers);
}

匹配
將DOM元素挨個傳入匹配器中,返回為true就是我們要找的目標(biāo)元素

var results = [];
var matcher = matcherFromTokens(tokens); // 生成匹配器

if (matcher(elem)) {
    results.push(elem)
}

總體流程就是這么回事

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容