jQuery插件命名空间
如何创建一个jQuery插件,以便我可以在我的插件中使用命名空间?
$("#id1").amtec.foo1(); $("#id1").amtec.foo2();
这些似乎都不起作用。
(function($) { var amtec = { $.fn.foo1 : function(){ return this.each(function(){}); }, $.fn.foo2 : function(){ return this.each(function(){}); } }; })(jQuery);
(function($) { $.fn.amtec = function(){ var foo1 = function(){ return this.each(function(){}); }; var foo2 = function(){ return this.each(function(){}); }; } })(jQuery);
(function($) { $.fn.amtec = function () { var jq = this; return { foo1: function(){ return jq.each(function(){}); }, foo2: function(){ return jq.each(function(){}); } } }; })(jQuery);
我知道我已经差不多三年了,但希望这个问题的未来读者可以从我的答案中受益。 从jQuery插件设计的角度来看, GSto的答案看起来很棒,但有一个小问题:使用新方法调用mynamespace()
clobbers返回的jQuery实例。 以下是一个问题的例子:
$myDiv = $('.mydiv'); $myDiv.mynamespace().height(); // this will be `height' from mynamespace $myDiv.height(); // this will STILL be `height' from mynamespace // because it has overwritten $myDiv.height
所选答案没有这个问题,因为amtec()
不是一个jQuery实例,而是一个用jQuery实例作为上下文调用其方法的对象。 我从两个答案中获取了概念并编写了下面的命名空间插件:
(function($) { $.namespace = function(namespaceName, closures) { if ($.fn[namespaceName] === undefined) { $.fn[namespaceName] = function executor(context) { if (this instanceof executor) { this.__context__ = context; } else { return new executor(this); } }; } $.each(closures, function(closureName, closure) { $.fn[namespaceName].prototype[closureName] = function() { return closure.apply(this.__context__, arguments); }; }); }; })(jQuery);
用法示例:
$.namespace('milosz', { redify: function() { $(this).css('color', '#ff0000'); }, greenify: function() { $(this).css('color', '#00ff00'); } }); $.namespace('milosz', { blueify: function() { $(this).css('color', '#0000ff'); } }); $('.mydiv').milosz().redify(); // The HTML elements with class `mydiv' are now red
该代码使用了一些非常低级的JavaScript细节,这些细节由John Resig的高级JavaScript教程很好地解释,但是松散地说这个例子中发生的事情是这样的:
当milosz
(内部$.fn[namespaceName]
)时, this
指向$('.mydiv')
返回的jQuery
实例。 因此, if
语句落入else
块并调用milosz
的构造函数版本(内部称为executor
,原因即将变得明显)。 构造函数传递一个参数: this
,指向jQuery
的指针,该实例将成为milosz
命名空间的所有成员的执行上下文。 我们回到if
语句,这次执行第一个块,其中传入的jQuery
实例存储在一个名为__context__
的成员变量中(希望被覆盖的可能性很小)。 返回构造的对象,完成对原始jQuery
实例的引用以及通过调用$.namespace
添加到其原型的任何包装器。 这些包装器只是将原始jQuery
对象作为上下文执行传递给milosz
命名空间的方法,就像执行redify
时redify
。
呸,我知道它是满口的,无论如何,重点是它的工作方式就像接受的答案,但看起来像是jQueryish的答案,对我来说这是两个世界中最好的。
(function($){ $.namespace = function(ns, functions){ $.fn[ns] = function() {return this.extend(functions)}; }; $.namespace('$', $.fn); // the default namespace })(jQuery);
所以现在你可以有一个插件:
$.fn.func = function(){alert('plugin'); return this'};
并在命名空间中创建插件:
$.namespace ('mynamespace', { func: function() {alert('namespaced plugin'); return this;}, otherfunc: function() {return this.css('color', 'yellow');} });
如果你这样做
$('div').func(); // alerts 'plugin' -- no namespace
但
$('div').mynamespace().func(); // alerts 'namespaced plugin'
和
$('div').mynamespace().func().$().func(); // alerts 'namespaced
插件’,然后重置为正常的jquery和警报’插件’
我知道这是一个老问题…但是为什么在你可以更换的时候写下所有这些额外的代码.
用_
?
$.fn.amtec_foo1 = function(){ return this.each(function(){}); } $.fn.amtec_foo2 = function(){ return this.each(function(){}); }
更好的是,给你的插件一个原始和项目不可知的名称。
$.fn.fooize = function(){ return this.html('Element has been Fooized!'); }
$.cg = { foo1: function(weq){ return console.log(weq); }, foo2: function(rw){ return console.log(rw); } }; $.cg = { // will result in error because $.cg is already declared above foo4: function(rw){ // will result in error return console.log(rw); // will result in error } // will result in error }; // will result in error $.cg.foo3 = function(weq){ //to add anything new to $.cg , you have to do it this way. return console.log(weq); } $.cg.foo1("12"); $.cg.foo2("22"); //works fine. $.cg.foo3("112"); //works fine.