jQuery扩展插件

什么是jQuery插件?

扩展jQuery原型对象的一个方法(jQuery插件是jQuery对象的一个方法)
jQuery插件的使用方式就是jQuery对象方法的调用。

jQuery.fn=jQuery.prototype

使用(jQuery插件如何使用?)

jQuery.fn.myPlugin = function() {

    // 插件的具体内容放在这里

};

$的冲突

把 jQuery 传递给 IIFE(立即调用函数),并通过它映射成 $ ,这样就避免了在执行的作用域里被其它库所覆盖。

(function( $ ) {
   $.fn.myPlugin = function() {
   
       // 插件的具体内容放在这里
   
   };
})( jQuery );

加分号的意义:
以 “(”、“[”、“/”、“+”、或 “-” 开始,那么它极有可能和前一条语句合在一起解释。
------《JavaScript 权威指南》
避免js代码压缩时出错

上下文中的this指向

在插件函数的立即作用域中,关键字 this 指向调用插件的 jQuery 对象。

(function( $ ){
    $.fn.myPlugin = function() {
    
        // 没有必要再作 $(this) ,因为"this"已经是 jQuery 对象了
        // $(this) 与 $($('#element')) 是相同的
           
        this.fadeIn('normal', function(){
            // 在这里 this 关键字指向 DOM 元素
        });                     
    };          
})( jQuery );

$('#element').myPlugin();

一个例子

(function( $ ){

  $.fn.maxHeight = function() {
  
    var max = 0;

    this.each(function() {
      max = Math.max( max, $(this).height() );
    });

    return max;
  };
})( jQuery );

var tallest = $('div').maxHeight(); // 返回最高 div 的高度

链式调用

在扩展函数的最后return this

(function( $ ){

  $.fn.lockDimensions = function( type ) {  

    return this.each(function() {

      var $this = $(this);

      if ( !type || type == 'width' ) {
        $this.width( $this.width() );
      }

      if ( !type || type == 'height' ) {
        $this.height( $this.height() );
      }

    });

  };
})( jQuery );

$('div').lockDimensions('width').css('color', 'red');

默认参数设置

除了$.extend()、也可以&&||短路操作符
$.extend(target, obj1, obj2, ...),它把多个object对象的属性合并到第一个target对象中,遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高。

(function( $ ){

  $.fn.tooltip = function( options ) {  

    //默认参数可以写在外面
    var settings = $.extend( {
      'location' : 'top',
      'background-color' : 'blue'
    }, options);

    return this.each(function() {

    });

  };
})( jQuery );

$('div').tooltip({
  'location' : 'left'
});    

$.fn 名称空间

(function( $ ){

  var methods = {
    init : function( options ) { 
      // 这 
    },
    show : function( ) {
      // 很
    },
    hide : function( ) { 
      // 好
    },
    update : function( content ) { 
      // !!! 
    }
  };

  $.fn.tooltip = function( method ) {
    
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    
  
  };

})( jQuery );

// 调用  init 方法
$('div').tooltip(); 

// 调用  init 方法
$('div').tooltip({
  foo : 'bar'
});

// 调用 hide 方法
$('div').tooltip('hide'); 

// 调用 update 方法
$('div').tooltip('update', 'This is the new tooltip content!');

事件,bind、unbind

bind方法支持为绑定事件定义名称空间。unbind的时候就不会影响到相同事件类型上的其它已绑定事件。

(function( $ ){

  var methods = {
     init : function( options ) {

       return this.each(function(){
         //把 reposition 方法绑定到 window 对象的 resize 事件上,名称空间为 "tooltip"。
         $(window).bind('resize.tooltip', methods.reposition);
       });

     },
     destroy : function( ) {

       return this.each(function(){
         //如果开发者想要销毁对象,可以把插件的名称空间(即 "tooltip")传给 unbind 方法,以便解除本插件对所有事件的绑定。
         //可以安全的地解除本插件的事件绑定,避免意外影响插件之外绑定的事件。
         $(window).unbind('.tooltip');
       })

     },
     reposition : function( ) { 
       // ... 
     },
     show : function( ) { 
       // ... 
     },
     hide : function( ) {
       // ... 
     },
     update : function( content ) { 
       // ...
     }
  };

  $.fn.tooltip = function( method ) {
    
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    
  
  };

})( jQuery );

$('#fun').tooltip();
// Some time later...
$('#fun').tooltip('destroy');

最佳实践

  1. 总是把插件包装在闭包中 { /* plugin goes here */ })( jQuery )。
  2. 不在插件函数的立即作用域中额外包装 this 关键字。
  3. 总是让插件函数返回 this 关键字以保持 chainability ,除非插件有真正的返回值。
  4. 不要传给插件大量参数,应该传一个可以覆盖插件默认选项的设置对象。
  5. 在单个插件中,不要让一个以上的名称空间搞乱了 jQuery.fn 对象。
  6. 总是为方法、事件和数据定义名称空间。

其它 $.fn.extend

(function($){
     $.fn.extend({         
         changeStyle: function(option){             
           var defaultSetting = { colorStr:"green",fontSize:12};
           var setting = $.extend(defaultSetting,option);
           this.css("color",setting.colorStr).css("fontSize",setting.fontSize+"px");        
           return this; 
          }
     });
}(jQuery));

$.extend方法和$.fn.extend方法都可以用来扩展jQuery功能,通过阅读jQuery源码我们可以发现这两个方法的本质区别,那就是$.extend方法是在jQuery全局对象上扩展方法,$.fn.extend方法是在$选择符选择的jQuery对象上扩展方法。所以扩展jQuery的公共方法一般用$.extend方法,定义插件一般用$.fn.extend方法。

jQuery插件集

针对特定元素的扩展filter

$.fn.external = function () {
    // return返回的each()返回结果,支持链式调用:
    return this.filter('a').each(function () {
        // 注意: each()内部的回调函数的this绑定为DOM本身!
        var a = $(this);
        var url = a.attr('href');
        if (url && (url.indexOf('http://')===0 || url.indexOf('https://')===0)) {
            a.attr('href', '#0')
             .removeAttr('target')
             .append(' ')
             .click(function () {
                if(confirm('你确定要前往' + url + '?')) {
                    window.open(url);
                }
            });
        }
    });
}

$('#main').external();
$('#main a').external();

jQuery.extend({...});静态方法

typeof jQuery==>"function"

jQuery.fn.extend({...});jQuery原型上的方法

jQuery.fn=jQuery.prototype

jQuery.extend({...})是给function jQuery添加静态属性或方法
jQuery().extend({...})是给jQuery对象添加属性或方法


额外:

扩展类方法:
jQuery.extend({
    fn1: function(){console.log('gyh')}
});
$.fn1(); // gyh
或者:
jQuery.fn2 = function(){console.log('gyh2')}
$.fn2();// gyh2

扩展实例方法(原型上的方法)
jQuery.fn.extend({
    fn1: function(){console.log(this)}
});
$('body').fn1(); // [body.library.Chrome, prevObject: init(1), context: document, selector: "body"]
或者:
jQuery.fn.fn2 = function(){console.log(this)}
$('head').fn2(); // [head, prevObject: init(1), context: document, selector: "head"]

你可能感兴趣的:(jQuery扩展插件)