jQuery插件的 开发包括两种:


一种是类级别的插件 开发,即给 jQuery添加新的全局函数,相当于给 jQuery类本身添加方法。 jQuery的全局函数就是属于 jQuery命名空间的函数,另一种是对象级别的插件开发,即给 jQuery对象添加方法。下面就两种函数的开发做详细的说明。


1、类级别的插件开发


jQuery类添加类方法,可以理解为添加静态方法。典型的例子就是 $.AJAX()这个函数,将函数定义于 jQuery的命名空间中。关于类级别的插件开发可以采用如下几种形式进行扩展:


1.1 添加一个新的全局函数


添加一个全局函数,我们只需如下定义:
 


JavaScript Code 复制内容到剪贴板


1. jQuery.foo = function() {   
2. alert('This is a test. This is only a test.');   
3. };


1.2 增加多个全局函数


添加多个全局函数,可采用如下定义:


JavaScript Code 复制内容到剪贴板



1. jQuery.foo = function() {    
2. alert('This is a test. This is only a test.');   
3. };   
4. jQuery.bar = function(param) {    
5. alert('This function takes a parameter, which is "' + param + '".');   
6. };    
7. 调用时和一个函数的一样的:jQuery.foo();jQuery.bar();或者$.foo();$.bar('bar');


1.3 使用jQuery.extend(object);



JavaScript Code 复制内容到剪贴板


1. jQuery.extend({       
2. foo: function() {       
3. alert('This is a test. This is only a test.');       
4. },       
5. bar: function(param) {       
6. alert('This function takes a parameter, which is "' + param +'".');       
7. }      
8. });



1.4 使用命名空间


jQuery命名空间中,我们禁止使用了大量的 javaScript函数名和变量名。但是仍然不可避免某些函数或变量名将于其他 jQuery插件冲突,因此我们习惯将一些方法封装到另一个自定义的命名空间。



JavaScript Code 复制内容到剪贴板


1. jQuery.myPlugin = {           
2. foo:function() {           
3. alert('This is a test. This is only a test.');           
4. },           
5. bar:function(param) {           
6. alert('This function takes a parameter, which is "' + param + '".');     
7. }          
8. };   
9. 采用命名空间的函数仍然是全局函数,调用时采用的方法:   
10. $.myPlugin.foo();          
11. $.myPlugin.bar('baz');

通过这个技巧(使用独立的插件名),我们可以避免命名空间内函数的冲突。


2、对象级别的插件开发



对象级别的插件开发需要如下的两种形式:、



1:  



JavaScript Code 复制内容到剪贴板

1. (function($){      
2. $.fn.extend({      
3. pluginName:function(opt,callback){      
4.           // Our plugin implementation code goes here.        
5. }      
6. })      
7. })(jQuery);


形式

2 :



JavaScript Code 复制内容到剪贴板


1. (function($) {        
2. $.fn.pluginName = function() {      
3.      // Our plugin implementation code goes here.      
4. };      
5. })(jQuery);


    上面定义了一个 jQuery 函数 , 形参是 $ ,函数定义完成之后 , 把 jQuery 这个实参传递进去 . 立即调用执行。这样的好处是 , 我们在写 jQuery 插件时 , 也可以使用 $ 这个别名 , 而不会与 prototype 引起冲突 .

2.1 在JQuery名称空间下申明一个名字



 $.fn.doSomething()和  $.fn.undoSomething()),那么你需要声明多个函数名字。但是,通常当我们编写一个插件时,力求仅使用一个名字来包含它的所有内容。我们的示例插件命名为“ highlight“     



JavaScript Code 复制内容到剪贴板


1. $.fn.hilight = function() {     
2.   // Our plugin implementation code goes here.     
3. };     
4. 我们的插件通过这样被调用:   
5. $('#myDiv').hilight();



但是如果我们需要分解我们的实现代码为多个函数该怎么办?有很多原因: 设计上的需要;这样做更容易或更易读的实现;而且这样更符合面向对象。这真是一个麻烦事,把功能实现分解成多个函数而不增加多余的命名空间。出于认识到和利用函数是 javascript中最基本的类对象,我们可以这样做。就像其他对象一样,函数可以被指定为属性。因此我们已经声明 “hilight”为 jQuery的属性对象,任何其他的属性或者函数我们需要暴露出来的,都可以在 "hilight" 函数中被声明属性。稍后继续。
2.2  接受options参数以控制插件的行为



options对象传递给插件函数。例如:
 



JavaScript Code 复制内容到剪贴板


1. // plugin definition     
2. $.fn.hilight = function(options) {     
3.   var defaults = {     
4.     foreground: 'red',     
5.     background: 'yellow'     
6.   };     
7.   // Extend our default options with those provided.     
8.   var opts = $.extend(defaults, options);     
9.   // Our plugin implementation code goes here.     
10. };     
11. 我们的插件可以这样被调用:   
12. $('#myDiv').hilight({     
13.   foreground: 'blue'     
14. });


2.3 暴露插件的默认设置



    



JavaScript Code 复制内容到剪贴板


1. // plugin definition     
2. $.fn.hilight = function(options) {     
3.   // Extend our default options with those provided.     
4.   // Note that the first arg to extend is an empty object -     
5.   // this is to keep from overriding our "defaults" object.     
6.   var opts = $.extend({}, $.fn.hilight.defaults, options);     
7.   // Our plugin implementation code goes here.     
8. };     
9. // plugin defaults - added as a property on our plugin function     
10. $.fn.hilight.defaults = {     
11.   foreground: 'red',     
12.   background: 'yellow'     
13. };      
14. 现在使用者可以包含像这样的一行在他们的脚本里:   
15. //这个只需要调用一次,且不一定要在ready块中调用   
16. $.fn.hilight.defaults.foreground = 'blue';     
17. 接下来我们可以像这样使用插件的方法,结果它设置蓝色的前景色:   
18. $('#myDiv').hilight();



如你所见,我们允许使用者写一行代码在插件的默认前景色。而且使用者仍然在需要的时候可以有选择的覆盖这些新的默认值:



// 覆盖插件缺省的背景颜色 
   
 
 
$.fn.hilight.defaults.foreground = 'blue'; 
 
 
// ... 
 
 
// 使用一个新的缺省设置调用插件 
   
 
 
$('.hilightDiv').hilight(); 
 
 
// ... 
 
 
// 通过传递配置参数给插件方法来覆盖缺省设置 
   
 
 
$('#green').hilight({ 
 
 
 foreground: 'green' 
 
 
});



2.4 适当的暴露一些函数



"format"的函数来格式化高亮文本。我们的插件现在看起来像这样,默认的 format方法的实现部分在 hiligth函数下面。



JavaScript Code 复制内容到剪贴板



    1. // plugin definition     
    2. $.fn.hilight = function(options) {     
    3.   // iterate and reformat each matched element     
    4.   return this.each(function() {     
    5.     var $this = $(this);     
    6.     // ...     
    7.     var markup = $this.html();     
    8.     // call our format function     
    9.     markup = $.fn.hilight.format(markup);     
    10.     $this.html(markup);     
    11.   });     
    12. };     
    13. // define our format function     
    14. $.fn.hilight.format = function(txt) {     
    15. return '<strong>' + txt + '</strong>';     
    16. };



    我们很容易的支持

    options 对象中的其他的属性通过允许一个回调函数来覆盖默认的设置。这是另外一个出色的方法来修改你的插件。这里展示的技巧是进一步有效的暴露 format 函数进而让他能被重新定义。通过这技巧,是其他人能够传递他们自己设置来覆盖你的插件,换句话说,这样其他人也能够为你的插件写插件。  


          考虑到这个篇文章中我们建立的无用的插件,你也许想知道究竟什么时候这些会有用。一个真实的例子是 Cycle 插件 . 这个 Cycle 插件是一个滑动显示插件,他能支持许多内部变换作用到滚动,滑动,渐变消失等。但是实际上,没有办法定义也许会应用到滑动变化上每种类型的效果。那是这种扩展性有用的地方。  Cycle 插件对使用者暴露 "transitions" 对象,使他们添加自己变换定义。插件中定义就像这样:

    $.fn.cycle.transitions = { 
     
     
    // ... 
     
     
    };



    Cycle插件。



    2.5 保持私有函数的私有性



    这种技巧暴露你插件一部分来被覆盖是非常强大的。但是你需要仔细思考你实现中暴露的部分。一但被暴露,你需要在头脑中保持任何对于参数或者语义的改动也许会破坏向后的兼容性。一个通理是,如果你不能肯定是否暴露特定的函数,那么你也许不需要那样做。



    “debug”函数到我们的插件中。这个  debug函数将为输出被选中的元素格式到 firebug控制台。为了创建一个闭包,我们将包装整个插件定义在一个函数中。 



    JavaScript Code 复制内容到剪贴板


    1.  (function($) {     
    2.   // plugin definition     
    3.   $.fn.hilight = function(options) {     
    4.     debug(this);     
    5.     // ...     
    6.   };     
    7.   // private function for debugging     
    8.   function debug($obj) {     
    9.     if (window.console && window.console.log)     
    10.       window.console.log('hilight selection count: ' + $obj.size());     
    11.   };     
    12. //  ...     
    13. })(jQuery);



    “debug”方法不能从外部闭包进入 ,因此对于我们的实现是私有的。



    2.6 支持Metadata插件



    Metadata插件的支持能使他更强大。个人来说,我喜欢这个 Metadata插件,因为它让你使用不多的 "markup”覆盖插件的选项(这非常有用当创建例子时)。而且支持它非常简单。更新:注释中有一点优化建议。



    JavaScript Code 复制内容到剪贴板

    1. $.fn.hilight = function(options) {     
    2.   // ...     
    3.   // build main options before element iteration     
    4.   var opts = $.extend({}, $.fn.hilight.defaults, options);     
    5.   return this.each(function() {     
    6.     var $this = $(this);     
    7.     // build element specific options     
    8.     var o = $.meta ? $.extend({}, opts, $this.data()) : opts;     
    9.     //...


    Metadata插件是否被安装如果它被安装了,它能扩展我们的 options对象通过抽取元数据这行作为最后一个参数添加到 JQuery.extend,那么它将会覆盖任何其它选项设置。现在我们能从 "markup”处驱动行为 ,如果我们选择了 “markup”:



     jQuery.foo(); 或  $.foo(); 



    JavaScript Code 复制内容到剪贴板



      1. <!--  markup  -->     
      2. <div class="hilight { background: 'red', foreground: 'white' }">     
      3.   Have a nice day!     
      4. </div>     
      5. <div class="hilight { foreground: 'orange' }">     
      6.   Have a nice day!     
      7. </div>     
      8. <div class="hilight { background: 'green' }">     
      9.   Have a nice day!     
      10. </div>     
      11. 现在我们能高亮哪些div仅使用一行脚本:   
      12. $('.hilight').hilight();



      2.7 整合
      下面使我们的例子完成后的代码:



      JavaScript Code 复制内容到剪贴板

      1. // 创建一个闭包     
      2. (function($) {     
      3.   // 插件的定义     
      4.   $.fn.hilight = function(options) {     
      5.     debug(this);     
      6.     // build main options before element iteration     
      7.     var opts = $.extend({}, $.fn.hilight.defaults, options);     
      8.     // iterate and reformat each matched element     
      9.     return this.each(function() {     
      10.       $this = $(this);     
      11.       // build element specific options     
      12.       var o = $.meta ? $.extend({}, opts, $this.data()) : opts;     
      13.       // update element styles     
      14.       $this.css({     
      15.         backgroundColor: o.background,     
      16.         color: o.foreground     
      17.       });     
      18.       var markup = $this.html();     
      19.       // call our format function     
      20.       markup = $.fn.hilight.format(markup);     
      21.       $this.html(markup);     
      22.     });     
      23.   };     
      24.   // 私有函数:debugging     
      25.   function debug($obj) {     
      26.     if (window.console && window.console.log)     
      27.       window.console.log('hilight selection count: ' + $obj.size());     
      28.   };     
      29.   // 定义暴露format函数     
      30.   $.fn.hilight.format = function(txt) {     
      31.     return '<strong>' + txt + '</strong>';     
      32.   };     
      33.   // 插件的defaults     
      34.   $.fn.hilight.defaults = {     
      35.     foreground: 'red',     
      36.     background: 'yellow'     
      37.   };     
      38. // 闭包结束     
      39. })(jQuery);


      这段 设计已经让我创建了强大符合规范的插件。我希望它能让你也能做到。



      3、总结



      jQuery为开发插件提拱了两个方法,分别是:



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



      3.1 jQuery.fn.extend(object);



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


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



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



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



      alert 当前编辑框里的内容。可以这么做:


      $.fn.extend({        
       
       
           alertWhileClick:function(){       
       
       
               $(this).click(function(){      
       
       
                    alert($(this).val());       
       
       
                });       
       
       
            }       
       
       
      });


      $("#input1").alertWhileClick(); //页面上为: <input id="input1" type="text"/>



      $("#input1") 为一个 jQuery实例,当它调用成员方法  alertWhileClick后,便实现了扩展,每次被点击时它会先弹出目前编辑里的内容。
       



      3.2 jQuery.extend(object);


      jQuery类添加添加类方法,可以理解为添加静态方法。如:



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



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