代码改变世界

jQuery插件开发

2013-10-06 04:44  youxin  阅读(519)  评论(0编辑  收藏  举报

Query插件的种类 

 jquery插件主要分为3种类型:
1、封装对象方法 

  这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常见的一种插件。此类插件可以发挥出jQuery选择器的强大优势,有相当一部分的jQuery的方法,都是在jQuery脚本库内部通过这种形式“插”在内核上的,例如parent()方法,appendTo()方法等。 

2、封装全局函数 

  可以将独立的函数加到jQuery命名空间下。如常用的jQuery.ajax()方法、去首尾空格的jQuery.trim()方法,都是jQuery内部作为全局函数的插件附加到内核上去的。 

3、选择器插件 

  虽然jQuery的选择器十分强大,但在少数情况下,还是会需要用到选择器插件来扩充一些自己喜欢的选择器。 

jQuery插件的机制 
  jQuery插件的机制很简单,就是利用jQuery提供的jQuery.fn.extend()和jQuery.extend()方法,扩展jQuery的功能。 

  jQuery.fn.extend()多用于扩展上面提到的3种类型中的第一种,jQuery.extend()用于扩展后两种插件。这两个方法都接受一个参数,类型为Object。Object对象的“名/值对”分别代表“函数或方法名/函数主体”。 

编写jQuery插件的一些Tips 
  1、jQuery插件的文件名推荐命名为jquery.[插件名].js,以免和其他JS库插件混淆。 

  2、所有的对象方法都应当附加到jQuery.fn对象上,而所有的全局函数都应当附加到jQuery对象本身。 

  3、在插件头部加上一个分号,以免他人的不规范代码给插件带来影响。 

  4、所有的方法或函数插件,都应当以分号结尾,以免压缩时出现问题 

  5、除非插件需要返回的是一些需要获取的变量,插件应该返回一个jQuery对象,以保证插件的可链式操作。 

  6、利于jQuery.extend()方法设置插件方法的默认参数,增加插件的可用性。 

 

在插件内部,this指向的是当前选择器获取的jquery对象,而不像一般的方法那样,例如click()方法,内部的this指向的是dom元素


 常见的Jquery插件都是以下这种形式:

;(function($){ 
/*这里放插件代码,可以将$作为jQuery的别名*/ 
})(jQuery); 

 

jquery提供了2个用于扩展jquery功能的方法,即

jQuery.fn.extend()和jQuery.extend()方法。前者注意用于扩展之前提到的3中类型插件中的第一种,后者用于扩展后2种插件。

这两种方法都接受一个参数,类型为Object,Object对象的“名/值对"分别代表”函数名或方法名/函数主体“。

jQuery.fn.extend( object )Returns: Object

Description: Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.

The jQuery.fn.extend() method extends the jQuery prototype ($.fn) object to provide new methods that can be chained to the jQuery() function. jquery.fn.extend()方法扩展jquery的原型($.fn)对象,来提供新jquery实例方法。

参考:http://api.jquery.com/jQuery.fn.extend/

jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。 
jQuery.fn.extend(object);给jQuery对象添加方法。

fn 是什么东西呢。查看jQuery代码,就不难发现

 

jQuery.fn = jQuery.prototype = { 
   init: function( selector, context ) {//....  
   //...... 
};

原来 jQuery.fn = jQuery.prototype.对prototype肯定不会陌生啦。 

虽然 javascript 没有明确的类的概念,但是用类来理解它,会更方便。 
jQuery便是一个封装得非常好的类,比如我们用 语句 $("#btn1") 会生成一个 jQuery类的实例。 

jQuery.extend(object); 为jQuery类添加添加类方法,可以理解为添加静态方法。如:

$.extend({ 
  add:function(a,b){return a+b;} 
}); 

便为 jQuery 添加一个为 add 的 “静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了, 
$.add(3,4); //return 7 

jQuery.fn.extend(object); 对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。

 (

    $.extend(dest,src1,src2,src3...)//也就是将"{}"作为dest参数。的extend方法原型中的dest参数是可以省略的,如果省略了,则该方法就只能有一个src参数,而且是将该src合并到调用extend方法的对象中去,如:
   $.extend(src)
   该方法就是将src合并到jquery的全局对象中去,如:

 $.extend({
hello:function(){alert('hello');}
});


   就是将hello方法合并到jquery的全局对象中。

 )

jquery.extend()方法除了可以用于扩展jQuery对象之外,还有一个强大的功能,就是用于扩展已有的Object对象

jQuery.extend( target [, object1 ] [, objectN ] )

Description: Merge the contents of two or more objects together into the first object.

用一个或多个其他对象来扩展一个对象,然后返回被扩展的对象。

例如合并setting对象和options对象,修改并返回setting对象。

var settings={validate:false,limit:5,name:"foo"};
var option={validate:true,name:"bar"};

var newOption=jQuery.extend(settings,option);

结果为:

newOption={validate:true,limit:5,name:"bar"}

 

jquery.extend()经常被用于设置插件方法的一些列默认参数,如下面的代码:

function foo(options)
{
    options=jQuery.extend({
        name:"bar",
        length:5,
        dataType:"xml" //默认参数
    },options); //options为传递的参数
    
}

 

1.封装jQuery对象方法插件 

该插件主要实现以下2个功能:

1.设置匹配元素的颜色

2.获取匹配的元素(元素集合中的第1个)的颜色

该插件命名:jquery.color.js

首先在js文件里搭好框架;

;(function($){
    
})(jQuery);

由于是对jquery对象的方法扩展,因此采用扩展第1类插件的方法jQuery.fn.extend()来编写:

;(function($){
    $.fn.extend({
        "color":function(value){
            //这里写插件代码
            
        }
    });
    
    
})(jQuery);

这里设置了一个参数value,如果调用时传递了value这个参数,就是设置颜色,否则为获取颜色。获取和设置颜色可以用jQuery提供的css方法即可。

首先实现第1个功能,设置字体的颜色,在函数内添加一句;

return this.css("color",value);

为插件内部的this指向的是Jquery对象,而非普通的Dom对象,上面的要注意的是,插件如果不需要返回字符串之类的特定值,应当使其具有可链接性。为此,直接返回this对象,由于.css()方法也会返回调用它的对象,即此处的this,所以上面的代码返回了jquery对象。

 

接下来实现第二个功能,如果没有传参就返回当前的颜色。判断一下value是否undefined就可以了。

;(function($){
    $.fn.extend({
        "clolor":function(value){
            if(value=='undefined')
            {
                return this.css("color");
            }
            else
            {
                return this.css("color",value);
            }
         
        }
    });
    
    
})(jQuery);

 

此时color插件的功能已经全部实现了。实际上,css()方法内部已经有判断value是否为undefined的机制,所以才可以根据传递参数的不同而返回不同的值。因此,可以借助css()方法这个特性来处理该问题,删除if()部分,最终剩余的代码实际上与先前的一样:

;(function($){
    $.fn.extend({
        "clolor":function(value){
             
                return this.css("color",value);
             
        }
    });
    
    
})(jQuery);

这样一来,插件编写完成了。

运行插件:

<script>
$(document).ready(function(e) {
    console.log($("div").color());//这是获取第1个div的color样式值,
  //将所有的div字体都设置成红色 console.log($(
"div").color("red"));//返回的jquery对象 }); </script> </head> <body> <div class="a">red</div> <div style="color:blue">blue</div> <div style="color:green">green</div> <div style="color:yellow">yellow</div>

注意获取时只获取第一个div的color值,设置时全都设置。

如果要定义一组插件,可以使用如下写法:

;(function($){ 
$.fn.extend({ 
"color":function(value){ 
//插件代码 
}, 
"border":function(value){ 
//插件代码 
}, 
"background":function(value){ 
//插件代码 
} 
}); 
})(jQuery); 

 插件测试: http://demo.jb51.net/js/2012/jquery_demo/封装jQuery对象方法插件Demo.html

 

插件开发模板;

(function ($) { 
//扩展 
$.fn.extend({ 
//插件名称 
height: function (options) { 
//默认参数 
var defaults = { 
  color: '红色' 
}; 
//覆盖默认参数 
var opts = $.extend(defaults, options); 
//主函数 
return this.each(function () { 
//激活事件 
  var obj = $(this); 
  obj.click(function () { 
  alert(opts.color); 
  }); 
 }); 
} 
}) 
})(jQuery); 
//注后面的(jQuery)一定要这样,Q一定要大写,j不能大写,不然出错。 

一般要return this.each

 

jquery tableUI功能:基数行和偶数行颜色不同,并且mouseover颜色改变。

 

// jquery table
cssStr='.evenRow { background-color:red; } ';
cssStr+='.oddRow { background-color:green;} ';
cssStr+='.activeRow{ background-color:yellow;} ';

document.write('<style type="text/css">'+ cssStr + '</style>');

(function($){
    $.fn.tableUI=function(options){
        var defaults={         
            evenRowClass:"evenRow", 
            oddRowClass:"oddRow", 
            activeRowClass:"activeRow" 
        };
        
        var options=$.extend(defaults,options)
        this.each(function(){
            var thisTable=$(this); //为什么要用$
            //添加奇偶行颜色 
            $(thisTable).find("tr:even").addClass(options.evenRowClass);
            $(thisTable).find("tr:odd").addClass(options.oddRowClass);
            
            //添加活动行颜色 
            $(thisTable).find("tr").mouseover(function(e) {
                $(this).addClass(options.activeRowClass);
            });
            $(thisTable).find("tr").mouseout(function(e) {
                $(this).removeClass(options.activeRowClass);
            });
            
        }); //end each
        
    };//end $.fn.tableUI

})(jQuery);

程序中用到了一个小技巧是在js写css,其中就是把css用字符串包围起来,然后用document.write()输出到页面。这种

参考:http://www.jb51.net/article/22849.htm

2.封装全局函数的插件

  这类插件是在jQuery命名空间内部添加一个函数,这里插件很简单,只是普通的函数,没有特别需要注意的地方。例如新增

2个函数,用于去除左侧和右侧的空格,虽然jquery提供了jQuery.trim()方法来去除2端空格,但在某些情况下,会只希望去除一端空。

function ltrim(text){
    return (text || "").replace(/^\s+/g,"");
}
function rtrim(text)
{
    return (text || "").replace(/\s+$/g,"");
}

(text || "")是为了防止传递进来的text处于未定义之类的特殊状态。如果text是undefined,则返回字符串"",否则返回text。这个

处理是为了保证接下来的字符串替换方法replace()方法不会出错。

函数写完之后,首先构造一个Object对象,把函数名和函数都放进去,如下:

{
     ltrim:function(text){
         return (text || "").replace(/^\s+/g,"");
     },
     rtrim:function(text){
         return (text || "").replace(/\s+$/g,"");
     }
}
    

然后,利用jQuery.extend()方法直接对jQuery对象进行扩展。

;(function($){
    $.extend( {
     ltrim:function(text){
         return (text || "").replace(/^\s+/g,"");
     },
     rtrim:function(text){
         return (text || "").replace(/\s+$/g,"");
      }
    });
    
})(jQuery);

测试代码:

<textarea id="trimText" rows="5" cols="20"></textarea>

$("#trimText").val(jQuery.rtrim("    test   ")); $.rtrim()也一样。

运行rtrim()后,右侧空格被删除。

 

 

3.选择器插件

jquery以其强大的选择器著称,但这并不表示其选择器尽善尽美,有时候web开发者希望有一些更强大的选择器。

 jquery提供了一套方法让用于可以通过制作选择器插件来使用自定义选择器,从而是jquery选择器更加完善。

jQuery的选择解析器首先会使用一组正则表达式来解析选择器,然后针对解析出的每一个选择符执行一个函数,称为选择函数。最后根据这个选择函数的返回值为true还是false来决定是否保留这个元素,这样就可以找到匹配的元素节点。 

  如$("div:gl(1)"),该选择器首先会获取所有的<div>元素,然后隐式地遍历这些<div>元素,并逐个将这些<div>元素作为参数,连同括号里的“1”等一些参数一起传递给gt对应的选择器函数进行判断。如果返回true则保留,否则不保留,这样得到的结果就是一个符合要求的<div>元素的集合。

:gt()选择器在jquery源文件中代码:

gt:function( a,i,m){

           return i>m[3]-0;

}

其中,选择器函数一共接受3个参数:a,i,m;

第一个参数a,指向的是当前遍历到的dom元素

第二个参数为i,指的是当前遍历到的dom元素的索引值,从0开始

第3个参数m最为特别,它是由jquey正则引擎进一步解析后的产物(用match匹配出来的),是一个数组

-m[0],以上面的$("div:gt(1)")作为例子,是:gt(1)这部分,他是jquery选择器进一步要匹配的内容。

-m[1],这里是选择器的引导符,匹配例子中的”:“,即冒号,并非只能使用:号后面跟上选择器,用户可以自定义其他的选择器引导符 。

-m[2],即例子中的gt,确定究竟是调用哪个选择器函数。

-m[3],即例子括号中的数字”1“,它非常有用,是编写选择器函数的最重要的一个参数。

m[4],比较罕见。

 

在jQuery中已经有lt,gt和eq选择器,因此这里写一个介于两者之间(between)的选择器。 

  功能:选择索引值为a到b之间(a<b,a、b为正整数)的元素

例如使用$("div:between(2,5)")能实现获取索引值为3,4元素的功能。

 

首先构建选择器函数;

function(a,i,m){
    var tmp=m[3].split(",");//将传进来的m[3]以逗号为分隔符,转成一个数组
    return  tmp[0]-0<i && i<tmp[1]-0; //例如 2<i<5
}

接下来,将这个函数扩展成jQuery的选择器:

;(function($){ 
$.extend($.expr[":"],{ 
between:function(a,i,m){ 
var temp=m[3].split(","); 
return +temp[0]<i&&i<+temp[1]; //写成return tmp[0]-0<i&&i<tmp[1]-0; 更好,功能都一样,把字符串转成数字
} 
}); 
})(jQuery); 

上面的程序我用jquery1.8.2运行不过,书上用的是v1.7.1可以运行,可能是该了某个部分。

 

 插件测试: http://demo.jb51.net/js/2012/jquery_demo/jQuery自定义选择器插件DEMO.html

主要参考:

<<锋利的jquery》单东林

http://www.jb51.net/article/29649.htm