zoukankan      html  css  js  c++  java
  • jQuery插件开发--(转)

    1,开始

    可以通过为jQuery.fn增加一个新的函数来编写jQuery插件。属性的名字就是你的插件的名字:

    1. jQuery.fn.myPlugin = function(){  
    2.     //开始写你的代码吧!  
    3. };  

     但是,那惹人喜爱的美元符号$哪里去了?她就是jQuery,但是为了确保你的插件与其他使用$的库不冲突,最好使用一个立即执行的匿名函数,这个匿名函数的参数是jQuery,这样其他的库就可以放心的使用$符号了。

    1. (function( $ ){  
    2.   $.fn.myPlugin = function() {  
    3.     
    4.     // 开始吧!  
    5.   
    6.   };  
    7. })( jQuery );  

     这样更好了就。在闭包内,可以放心的使用$符号了~

    2,上下文

    现在已经可以编写我们的代码了,但是编写之前,我必须说一说上下文。在插件内部的范围中,this关键字指向的是jQuery对象。人们很容易误解这一点,因为在正常使用jQuery的时候,this通常指向的是一个DOM元素。不了解这一点,会经常使用$又包装了一次。

    1. (function( $ ){  
    2.   
    3.   $.fn.myPlugin = function() {  
    4.     
    5.     // 没有必要使用$(this)  
    6.   
    7.     // $(this) 跟 $($('#element'))是一样的  
    8.           
    9.     this.fadeIn('normal', function(){  
    10.   
    11.       //这里的this指的就是一个DOM元素了  
    12.   
    13.     });  
    14.   
    15.   };  
    16. })( jQuery );  
    17.   
    18. $('#element').myPlugin();  

    3,基本开发 

    接下来写一个能用的插件吧。

    1. (function( $ ){  
    2.   
    3.   $.fn.maxHeight = function() {  
    4.     
    5.     var max = 0;  
    6.   
    7.     this.each(function() {  
    8.       max = Math.max( max, $(this).height() );  
    9.     });  
    10.   
    11.     return max;  
    12.   };  
    13. })( jQuery );  
    1. var tallest = $('div').maxHeight();  

     这是一个简单的插件,通过调用height()返回页面上height最大的div的height。

    4,维护链式开发的特性

    上一个例子是返回了一个整数,但是大多数情况下,一个插件紧紧是修改收集到的元素,然后返回这个元素让链条上的下一个使用。这是jQuery设计的精美之处,也是jQuery如此流行的原因之一。为了保证可链式,你必须返回this。

    1. (function( $ ){  
    2.   
    3.   $.fn.lockDimensions = function( type ) {    
    4.   
    5.     return this.each(function() {  
    6.   
    7.       var $this = $(this);  
    8.   
    9.       if ( !type || type == 'width' ) {  
    10.         $this.width( $this.width() );  
    11.       }  
    12.   
    13.       if ( !type || type == 'height' ) {  
    14.         $this.height( $this.height() );  
    15.       }  
    16.   
    17.     });  
    18.   
    19.   };  
    20. })( jQuery );  
    1. $('div').lockDimensions('width').css('color','red');  

     因为该插件返回了this,所以保证了可链式,从而可以继续使用jQuery方法进行修改,如css()。如果你的插件如果不是返回一个简单值,你通常应该返回this。而且,正如你可能想到的,你传进去的参数也可以在你的插件中访问。所以在这个例子中,可以访问到type。

    5,默认值和选项

    为了一些复杂的,可订制的插件,最好提供一套默认值,在被调用的时候扩展默认值。这样,调用函数的时候就不用传入一大堆参数,而是传入需要被替换的参数。你可以这样做:

    1. (function( $ ){  
    2.   
    3.   $.fn.tooltip = function( options ) {    
    4.   
    5.     var settings = {  
    6.       'location'         : 'top',  
    7.       'background-color' : 'blue'  
    8.     };  
    9.   
    10.     return this.each(function() {          
    11.       // 如果存在选项,则合并之  
    12.       if ( options ) {   
    13.         $.extend( settings, options );  
    14.       }  
    15.   
    16.       // 其他代码咯  
    17.   
    18.     });  
    19.   
    20.   };  
    21. })( jQuery );  
    1. $('div').tooltip({'location':'left'});  

     在这个例子中,调用插件后,默认的location会被替换城'left',而background-color还是'blue'。这样可以保证高度可配置性,而不需要开发者定义所有可能的选项了。

    6,命名空间

    正确的命名空间对于插件开发十分重要,这样能确保你的插件不被其他插件重写,也能避免被页面上其他代码重写。命名空间可以使你更长寿,因为你能记录你自己的方法,事件,数据等。

    a,插件方法

    在任何情况下,都不要在一个插件中为jQuery.fn增加多个方法。如:

    1. (function( $ ){  
    2.   
    3.   $.fn.tooltip = function( options ) { // 这样 };  
    4.   $.fn.tooltipShow = function( ) { // 是   };  
    5.   $.fn.tooltipHide = function( ) { // 不好的  };  
    6.   $.fn.tooltipUpdate = function( content ) { // 同学!  };  
    7.   
    8. })( jQuery );  

     不推荐这样使用,搞乱了$.fn命名空间。要纠正之,你可以把所有的方法放进一个对象中,然后通过不同的参数来调用。

    1. (function( $ ){  
    2.   
    3.   var methods = {  
    4.     init : function( options ) { // THIS },  
    5.     show : function( ) { // IS   },  
    6.     hide : function( ) { // GOOD },  
    7.     update : function( content ) { // !!! }  
    8.   };  
    9.   
    10.   $.fn.tooltip = function( method ) {  
    11.       
    12.     // Method calling logic  
    13.     if ( methods[method] ) {  
    14.       return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));  
    15.     } else if ( typeof method === 'object' || ! method ) {  
    16.       return methods.init.apply( this, arguments );  
    17.     } else {  
    18.       $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );  
    19.     }      
    20.     
    21.   };  
    22.   
    23. })( jQuery );  
    1. $('div').tooltip({  // calls the init method  
    2.   foo : 'bar'  
    3. });  
    4. $('div').tooltip('hide'); // calls the hide method  
    5. $('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method  

    jQuery自己的扩展也是使用这种插件结构。

    b,事件

    绑定事件的命名空间是比较不为人知的。如果你的插件绑定了某个事件,最好将它搞到一个命名空间中。这样,如果你以后需要解绑,就不会影响到其他绑定到这个事件上的函数了。你可以使用".<namespace>"来增加命名空间。

    1. (function( $ ){  
    2.   
    3.   var methods = {  
    4.      init : function( options ) {  
    5.   
    6.        return this.each(function(){  
    7.          $(window).bind('resize.tooltip', methods.reposition);  
    8.        });  
    9.   
    10.      },  
    11.      destroy : function( ) {  
    12.   
    13.        return this.each(function(){  
    14.          $(window).unbind('.tooltip');  
    15.        })  
    16.   
    17.      },  
    18.      reposition : function( ) { // ... },  
    19.      show : function( ) { // ... },  
    20.      hide : function( ) { // ... },  
    21.      update : function( content ) { // ...}  
    22.   };  
    23.   
    24.   $.fn.tooltip = function( method ) {  
    25.       
    26.     if ( methods[method] ) {  
    27.       return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));  
    28.     } else if ( typeof method === 'object' || ! method ) {  
    29.       return methods.init.apply( this, arguments );  
    30.     } else {  
    31.       $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );  
    32.     }      
    33.     
    34.   };  
    35.   
    36. })( jQuery );  
    37.   
    38. $('#fun').tooltip();  
    39. // Some time later...  
    40. $('#fun').tooltip('destroy');  

    在这个例子中,tooltip在init方法中初始化,它将reposition方法绑定到window对象的resize事件的tooltip名字空间下。稍候,如果开发者需要去掉这个tooltip,我们可以解绑这个绑定。这样就不会影响到其他绑定到window对象的resize事件的方法了。

    c,数据

    在开发插件的时候,你通常会有保持状态或者检查你的插件是否已经初始化的需要。使用jQuery的data方法是保持变量的很好的方法。但是,我们不把变量单独保存,而是放在一个对象中,这样就可以在一个名字空间下统一访问了。

    1. (function( $ ){  
    2.   
    3.   var methods = {  
    4.      init : function( options ) {  
    5.   
    6.        return this.each(function(){  
    7.            
    8.          var $this = $(this),  
    9.              data = $this.data('tooltip'),  
    10.              tooltip = $('<div />', {  
    11.                text : $this.attr('title')  
    12.              });  
    13.            
    14.          // If the plugin hasn't been initialized yet  
    15.          if ( ! data ) {  
    16.            
    17.            /* 
    18.              Do more setup stuff here 
    19.            */  
    20.   
    21.            $(this).data('tooltip', {  
    22.                target : $this,  
    23.                tooltip : tooltip  
    24.            });  
    25.   
    26.          }  
    27.        });  
    28.      },  
    29.      destroy : function( ) {  
    30.   
    31.        return this.each(function(){  
    32.   
    33.          var $this = $(this),  
    34.              data = $this.data('tooltip');  
    35.   
    36.          // Namespacing FTW  
    37.          $(window).unbind('.tooltip');  
    38.          data.tooltip.remove();  
    39.          $this.removeData('tooltip');  
    40.   
    41.        })  
    42.   
    43.      },  
    44.      reposition : function( ) { // ... },  
    45.      show : function( ) { // ... },  
    46.      hide : function( ) { // ... },  
    47.      update : function( content ) { // ...}  
    48.   };  
    49.   
    50.   $.fn.tooltip = function( method ) {  
    51.       
    52.     if ( methods[method] ) {  
    53.       return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));  
    54.     } else if ( typeof method === 'object' || ! method ) {  
    55.       return methods.init.apply( this, arguments );  
    56.     } else {  
    57.       $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );  
    58.     }      
    59.     
    60.   };  
    61.   
    62. })( jQuery );  

     使用data方法可以帮助你在插件的各个方法间保持变量和状态。将各种变量放在一个对象中,可以方便访问,也可以方便移除。

    7,总结与最佳实践

    编写jQuery插件可以充分利用库,将公用的函数抽象出来,“循环利用”。以下是简短的总结:

    • 使用(function($){//plugin})(jQuery);来包装你的插件
    • 不要在插件的初始范围中重复包裹
    • 除非你返回原始值,否则返回this指针来保证可链式
    • 不要用一串参数,而是使用一个对象,并且设置默认值
    • 一个插件,不要为jQuery.fn附上多个函数
    • 为你的函数,事件,数据附着到某个命名空间
  • 相关阅读:
    HUNAN 11562 The Triangle Division of the Convex Polygon(大卡特兰数)
    HUNAN 11560 Yangyang loves AC(二分+贪心)
    CSU 1425 Prime Summation
    CSU 1424 Qz’s Maximum All One Square
    一个奇怪的语法问题
    CSU 1416 Practical Number
    CSU 1412 Line and Circles
    Android第一篇
    强大到无与伦比的Graphviz
    CSU 1355 地雷清除计划
  • 原文地址:https://www.cnblogs.com/amylis_chen/p/4469922.html
Copyright © 2011-2022 走看看