我的插件一般看起来像这样:
(function($) { $.fn.myplugin = function(...) { ... // some shared functionality,for example: this.css('background-color','green'); ... }; $.fn.mypluginAnotherPublicMethod = function(...) { ... // some shared functionality,'red'); ... }; }(jQuery));
现在我的问题是:如何整齐地将这种共享功能干涸?一个明显的解决方案是将其放在插件的命名空间中的一个函数中:
var fill = function($obj,color) { $obj.css('background-color',color); };
虽然这个解决方案是有效和命名空间,我真的不喜欢它.一个简单的原因:我必须传递它的jQuery对象.即我必须像这样调用:fill(this,’red’);而我想像这样调用:this.fill(‘red’);
当然,我们可以通过简单的填入jQuery.fn来实现这个结果.但这感觉很不舒服想象一下,根据这种方法开发了十个插件,每个插件将其中的五个“私有”功能放入jQuery函数命名空间中.它结束了一大堆混乱.我们可以通过将这些功能中的每个功能与他们所属的插件的名称进行前缀来减轻,但这并不意味着它更具吸引力.这些功能应该是插件的私有的,所以我们不想将它们暴露给外界(至少不是直接的).
所以有我的问题:有没有人对如何获得两个世界最好的建议.那是;插件代码能够以类似于this.fill(‘red’)(或this.myplugin.fill(‘red’)或甚至this.myplugin()的方式调用’private’插件函数fill(‘red’)等等),同时防止jQuery函数命名空间污染.当然,它应该是轻量级的,因为这些私人职能可能被频繁地叫出来.
更新:感谢您的建议.
我特别喜欢David的定义一个保存’private’函数并包装一个jQuery对象的对象类型的想法.唯一的问题是它仍然禁止我链接“私人”和“公共”功能.想要像this.fill(‘red’)这样的语法开始就是很大的理由.
我结束了一个解决方案,我认为这不是非常优雅,而是吸引着“两个世界最好的”事业:
$.fn.chain = function(func) { return func.apply(this,Array.prototype.slice.call(arguments,1)); };
其中允许的结构如下:
this. find('.acertainclass'). chain(fill,'red'). click(function() { alert("I'm red"); });
我在其他地方交叉发布了我的问题,也收集了一些有趣的回答:
> http://forum.jquery.com/topic/jquery-plugin-design-pattern-common-practice-for-dealing-with-private-functions
> http://groups.google.com/group/jquery-en/browse_thread/thread/fa8ccef21ccc589a
解决方法
在jQuery回调中,这通常是对HTML元素的引用,并且您不能向这些(还)添加原型.这就是为什么jQuery包装元素并返回可以轻松扩展的jQuery实例的原因之一.
使用(function(){})();语法,您可以快速创建和执行“私有”javascript,并且完成后都会消失.使用这种技术,您可以创建自己的类似jQuery的语法,将jQuery包装到您自己的私有可链接对象中.
(function(){ var P = function(elem) { return new Private(elem); }; var Private = function(elem) { this.elem = jQuery(elem); } Private.prototype = { elem: null,fill: function(col) { this.elem.css('background',col); return this; },color: function(col) { this.elem.css('color',col); return this; } } $.fn.myplugin = function() { P(this).fill('red'); }; $.fn.myotherplugin = function() { P(this).fill('yellow').color('green'); }; })(); $('.foo').myplugin(); $('.bar').myotherplugin(); console.log(typeof P === 'undefined') // should print 'true'
这样,P代表您自己的“私有”功能的工具箱.除了将它们附加到某个地方,它们将不会在代码或jQuery命名空间中的其他位置上使用.您可以在Private对象中添加任意多种方法,只要返回此类型,您也可以像我在示例中一样连接jQuery样式.