標籤:style blog color 使用 os io strong 檔案
很多人是因為jQuery的強大選取器而愛上它的(沒錯,我就是特別討厭原生JS的FindElementById),但是何嘗不想把一些經常用的鏈式操作組合寫成一個選取器呢?!
從機制上來講,jQuery的選擇符解析器首先會使用一組Regex來解析選取器,然後對解析出來的每個選擇符執資料列選取器函數,最後根據true或false來決定是否保留元素。
比如說:
$(‘div:gt(1)‘)
在jQuery的源檔案中是由jQuery.expr[":"] = jQuery.expr.pseudos 對象來維護選取器的,所以我們擴充的時候,也就是要擴充這個對象。
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes;}
matchIndexes,就是需要返回的DOM元素,length就是DOM的元素總數,argument就是gt()裡的參數
代碼中可以看出i從argument+1開始遞增,直到元素總數。所有的這些index都會被選擇出來,最後return回去。
function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); });}
選取器的工作就完成了!(看不懂原始碼也沒關係,接下來才是關鍵)
假如我們自己要寫一個between的選取器,該怎麼做呢?利用(a,i,m)參數傳入
a: 當前遍曆到的DOM元素
i:當前遍曆到的DOM元素index,從0開始
m:正則解析的結果,m[0]: ":gt(1)", m[1]: ":", m[2]: "gt(1)", m[3]: "1"(因此M[3]就是我們自訂選取器的傳入參數!)
;(function($){ $.extend($.expr[":"],{ //這裡利用extend對jQuery.expr[":"]這個對象進行擴充 between: function(a,i,m){ var tmp=m[3].split(","); //以逗號分隔,切成一個數組 return tmp[0]-0<i&&i<tmp[1]-0; } });})(jQuery);//外掛程式應用$(function(){ $("div:between(2,10)").css("color","red");})
選取器外掛程式比較晦澀難懂,涉及到內部的解析引擎,需要仔細去分析jQuery的原始碼才能領會其中的奧妙。