jQuery插件创作和命名空间

我习惯这样编写插件:

;(function($){jQuery.fn.myPlugin=function(options){ var defaults={ 'property':value }, o=$.extend({},defaults,options||{}); // INSERT AND CACHE ELEMENTS var $Element=$('
'); $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=$('
') .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有什么好处吗?

非常感谢任何人和每个人! 🙂

更仔细地查看“工具提示”示例插件。 这是一个真正伟大的模式。

它完成了你所需要的所有命名空间,并且已经是你习惯的类型,至少底部的通用“主管”块是 – 即这部分:

 $.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术语中的私有变量,但其属性作为插件的方法以主管非常聪明,非常规的方式公开。

Pleeeease不会尝试将defaults / options代码移出init方法。 这会把一切都搞砸了! 遵循久经考验的模式,一切都会好的。

编辑:

一定要坚持模式的其他方面:

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

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

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