很多人是因为jQuery的强大选择器而爱上它的(没错,我就是特别讨厌原生JS的FindElementById),但是何尝不想把一些经常用的链式操作组合写成一个选择器呢?!
从机制上来讲,jQuery的选择符解析器首先会使用一组正则表达式来解析选择器,然后对解析出来的每个选择符执行选择器函数,最后根据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的源代码才能领会其中的奥妙。
JQuery插件编写之定制版选择器,布布扣,bubuko.com
时间: 2024-11-03 21:16:03