1. 程式人生 > >jQuery原始碼研究:選擇器

jQuery原始碼研究:選擇器

jQuery的css選擇器,是一大亮點,其實現原始碼也可單獨拎出來作為模組使用。

先看個整體,在jQuery原始碼中在行229-2752區域。

var Sizzle = (function(window){
    // 具體實現暫略...
})(window)

css選擇器的具體實現是一個匿名自執行函式,傳入引數為window物件。函式頂部定義若干變數,包括本地文件變數、特定例項資料和特定例項方法,此外還定義了一些為選擇器字串服務的正則表示式。數量太多就不一一列舉了,感興趣的可以自己去看原始碼吧。

方法的主體從行715開始直到結束,定義了Sizzle建構函式,若干工具方法和Sizeele

靜態方法及屬性,概覽看下圖,由於內容太多,只截部分:
圖1

1、Sizzle建構函式:

function Sizzle( selector, context, results, seed ){
    var m, i, elem, nid, match, groups, newSelector,
		newContext = context && context.ownerDocument,
        //上下文預設為document,節點型別預設為9
		nodeType = context ? context.nodeType : 9;
	results = results ||
[]; // 對選擇器值為非字串、為假、節點型別不符合要求時的返回值進行處理 if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // 操作HTML文件 if ( !seed ) { if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
setDocument( context ); } context = context || document; if ( documentIsHTML ) { if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // ID 選擇器 if ( (m = match[1]) ) { // 文件內容 if ( nodeType === 9 ) { if ( (elem = context.getElementById( m )) ) { if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // 元素內容 } else { if ( newContext && (elem = newContext.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // 型別選擇器 } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class 選擇器 } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } if ( support.qsa && !compilerCache[ selector + " " ] && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( nodeType !== 1 ) { newContext = context; newSelector = selector; } else if ( context.nodeName.toLowerCase() !== "object" ) { if ( (nid = context.getAttribute( "id" )) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", (nid = expando) ); } groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[i] = "#" + nid + " " + toSelector( groups[i] ); } newSelector = groups.join( "," ); newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; } if ( newSelector ) { try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } } // 返回 呼叫select()方法後的值 return select( selector.replace( rtrim, "$1" ), context, results, seed ); }

Sizzle函式是整個css選擇器的入口函式。

喜歡本文請掃下方二維碼,關注微信公眾號: 前端小二,檢視更多我寫的文章哦,多謝支援。
在這裡插入圖片描述