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的源代码才能领会其中的奥妙。

 

JQuery插件编写之定制版选择器,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。