jQuery選取器代碼詳解(二)——select方法

來源:互聯網
上載者:User

jQuery選取器代碼詳解(二)——select方法

原創文章,轉載請註明出處,多謝!

 

/* * select方法是Sizzle選取器包的核心方法之一,其主要完成下列任務: * 1、調用tokenize方法完成對選取器的解析 * 2、對於沒有初始集合(即seed沒有賦值)且是單一塊選取器(即選取器字串中沒有逗號), *    完成下列事項: *    1) 對於首選取器是ID類型且context是document的,則直接擷取對象替代傳入的context對象 *    2) 若選取器是單一選取器,且是id、class、tag類型的,則直接擷取並返回匹配的DOM元素 *    3) 擷取最後一個id、class、tag類型選取器的匹配DOM元素賦值給初始集合(即seed變數) *    4) 通過調用compile方法擷取“先行編譯”代碼並執行,擷取並返回匹配的DOM元素 *  * @param selector 已去迴轉尾空白的選取器字串 * @param context 執行匹配的最初的上下文(即DOM元素集合)。若context沒有賦值,則取document。 * @param results 已匹配出的部分最終結果。若results沒有賦值,則賦予空數組。 * @param seed 初始集合 */function select(selector, context, results, seed) {var i, tokens, token, type, find, // 調用tokenize函數解析selectormatch = tokenize(selector);// 若沒有提供初始集合if (!seed) {// Try to minimize operations if there is only one group// 若只有一組選取器,即選取器字串沒有逗號if (match.length === 1) {// Take a shortcut and set the context if the root selector// is an ID/* * 下面代碼是用來處理根選取器是ID類型的捷徑 *  * 在此使用slice[0]來建立一個新的集合, * 確保原有的集合不會被之後代碼變更掉 */tokens = match[0] = match[0].slice(0);/* * 若選取器是以id類型開始,且第二個是關係符(即+~>或空格), * 則擷取id所屬對象作為context繼續完成後續的匹配 *  * 此處的條件判斷依次為: * tokens.length > 2 :若tokens有兩個以上的選取器 * (token = tokens[0]).type === ID :第一個選取器的類型為ID(即以#開頭的), * support.getById :支援getElementById函數 * context.nodeType === 9 :context對象是document * documentIsHTML :當前處理的是HTML代碼 * Expr.relative[tokens[1].type] :第二個tokens元素是一個關係(即+~>或空格) * 在滿足上面所有條件的情況下,執行if內的語句體 */if (tokens.length > 2 && (token = tokens[0]).type === ID&& support.getById && context.nodeType === 9&& documentIsHTML && Expr.relative[tokens[1].type]) {// 將當前上下文指向第一個ID選取器指定的節點對象context = (Expr.find[ID](token.matches[0].replace(runescape, funescape), context) || [])[0];// 若當前上下文內沒有指定ID對象,則直接返回resultsif (!context) {return results;}// 選取器字串去掉第一個ID選取器selector = selector.slice(tokens.shift().value.length);}// Fetch a seed set for right-to-left matching/*  * 下面while迴圈的作用是用來根據最後一個id、class、tag類型的選取器擷取初始集合 * 舉個簡單例子:若選取器是div[title='2'], * 代碼根據div擷取出所有的context下的div節點,並把這個集合賦給seed變數, * 然後在調用compile函數,產生先行編譯代碼, * 先行編譯程式碼完成在上述初始集合中執行[title='2']的匹配 *  * 首先,檢查選取器字串中是否存在與needsContextRegex相匹配的字元 * 若沒有,則將依據選取器從右至左過濾DOM節點 * 否則,將先產生先行編譯代碼後執行(調用compile方法)。  *//* * needsContext : new RegExp(^ + whitespace *+ *[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\( *+ whitespace + *((?:-\d)?\d*) + whitespace *+ *\)|)(?=[^-]|$), i) * needsContext用來匹配選取器字串中是否包含下列內容: * 1、>+~三種關係符 * 2、:even、:odd、:eq、:gt、:lt、:nth、:first、:last八種偽類 * 其中,(?=[^-]|$)用來過濾掉類似於:first-child等帶中杠的且以上述八個單詞開頭的其它選取器 */i = matchExpr[needsContext].test(selector) ? 0: tokens.length;while (i--) {token = tokens[i];// Abort if we hit a combinator// 遇到關係符跳出迴圈if (Expr.relative[(type = token.type)]) {break;}if ((find = Expr.find[type])) {// Search, expanding context for leading sibling// combinators/* * rsibling = new RegExp(whitespace + *[+~]) * rsibling用於判定token選取器是否是兄弟關係符 */if ((seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type)&& context.parentNode || context))) {// If seed is empty or no tokens remain, we can// return early// 剔除剛用過的選取器tokens.splice(i, 1);selector = seed.length && toSelector(tokens);/* * 若selector為空白,說明選取器僅為單一id、class、tag類型的, * 故直接返回擷取的結果,否則,在擷取seed的基礎上繼續匹配 */if (!selector) {push.apply(results, seed);return results;}break;}}}}}// Compile and execute a filtering function// Provide `match` to avoid retokenization if we modified the// selector above/* * 先執行compile(selector, match),它會返回一個“先行編譯”函數, * 然後調用該函數擷取最後匹配結果 */compile(selector, match)(seed, context, !documentIsHTML, results,rsibling.test(selector));return results;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.