jQuery插件创作和命名空间

时间:2012-09-28 01:25:33

标签: javascript jquery plugins javascript-namespaces

我习惯于像这样编写插件:

;(function($){jQuery.fn.myPlugin=function(options){
    var defaults={
        'property':value
    },
    o=$.extend({},defaults,options||{});

   // INSERT AND CACHE ELEMENTS
   var $Element=$('<div></div>');
   $Element.appendTo($('body'));

function funFunction(){
  // I have access to $Element!
 $Element.hide(500);
};

this.each(function(i){
     var $this=$(this);
});
return this;
});};})(jQuery);

我知道它并不完美,这就是为什么我现在正在尝试正确学习命名空间,更好的插件结构/模式。不幸的是,我读过的几本书不经意地逐字引用了jQuery插件创作教程,所以没有多大帮助。该教程似乎将所有内容分开,并没有显示组合的良好示例,这就是为什么我感到困惑。在本教程中,它显示了命名空间示例。

jQuery插件命名空间教程

(function( $ ){
  var methods = {
    init : function( options ) { 
    },
    show : function( ) {
    },
    hide : function( ) { 
    },
    update : function( content ) { 
    }
  };

  $.fn.tooltip = function( method ) {
    // Method calling logic
    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 );
// calls the init method
$('div').tooltip(); 

我理解结构以及如何访问命名空间对象,但是它显示了默认值/选项的另一个示例,不包括任何命名空间......所以为了编写正确命名空间的插件的开头,有默认值/选项并缓存我插入的HTML元素,以便在整个插件中使用,我想出了以下内容。

正确组合?

;(function($,window,document,undefined){
var myPlugin={
    // METHODS
    init:function(options){

    },
    buildElements:function(){ 
        var $Elements=$('<div id="myElem"></div>')
                    .appendTo($('body'));
       }
};

$.fn.myPlugin=function(method,options){
    var defaults={

    },
    options=$.extend({},defaults,options||{});

    myPlugin.buildElements();

    return this.each(function(){
        var $this=$(this);
        if(myPlugin[method]){
          return myPlugin[method].apply(this,Array.prototype.slice.call(arguments,1));
        }else if(typeof method==='object'||!method){
          return myPlugin.init.apply(this,arguments);
        }else{$.error('Method '+method+' does not exist on jQuery.myPlugin');};
    });
};})(jQuery);
  1. 显然,当我构建/插入myElem时,它只能在该方法中使用,而不是在其他任何内部....我是否在错误的地方构建它?

  2. 默认值/扩展名是否正确?

  3. 如果我不想从插件外部访问方法,我是否需要方法逻辑部分?

  4. 使用.prototype vs .fn?

  5. 有什么好处

    非常感谢任何人和大家! :)

1 个答案:

答案 0 :(得分:7)

查看&#34;工具提示&#34;示例插件更仔细。这是一个真正伟大的模式。

它完成了您所需要的所有命名空间,并且已经是您习惯的类型,至少是广义的&#34;主管&#34;底部的块是 - 即这部分:

$.fn.tooltip = function( method ) {
    // Method calling logic
    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' );
    }    
};

methods是一个直接javascript术语中的私有变量,但其属性作为插件的方法以主管非常聪明,非常规的方式公开。

请不要尝试将默认值/选项代码移出init方法。这会把一切都搞砸了!遵循久经考验的模式,一切都会好的。

编辑:

请务必遵守该模式的其他方面:

  • 要维护jQuery对象的可链接性,请在每个不返回特定结果的方法中使用return this.each(function(){...})结构。
  • (通常),在init中,建立一个.data('pluninName', {...})对象以容纳在初始化时建立的任何数据,并且需要稍后由其他插件方法访问/修改/扩充。

该模式只为插件本身提供了一个闭包(包含methods对象);闭包的命名空间不能用于特定于元素的数据(包括初始化选项),因此需要使用.data('pluninName', ...)

这些不仅仅是惯例 - 它们绝对是使模式按预期工作的关键。