首页 > 代码库 > JQuery插件编写之定制版选择器

JQuery插件编写之定制版选择器

很多人是因为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的源代码才能领会其中的奥妙。