2009-10-08 55 views
25

如何創建一個jQuery插件,以便我可以在我的插件中使用命名空間?jQuery Plugin命名空間

$("#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); 
+0

請問你看看我的解決方案。對你想要達到的目標更準確。 – 2014-10-28 16:45:41

回答

21
(function($) { 
    $.fn.amtec = function() { 
     var jq = this; 
     return { 
      foo1: function(){ 
       return jq.each(function(){}); 
      }, 

      foo2: function(){ 
       return jq.each(function(){}); 
      } 
     } 
    }; 
})(jQuery); 
+0

Alexander,FireBug中的錯誤控制檯顯示: this.each不是函數 – MotionGrafika 2009-10-08 14:14:50

+0

我想我搞砸了 - 我已經更新了我的答案。 – 2009-10-08 18:49:01

+4

非常感謝亞歷山大!它的工作,但作爲 $(「#id1」)。amtec()。foo1(); 而不是 $(「#id1」)。amtec.foo2(); – MotionGrafika 2009-10-09 05:07:56

3
(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和警報 '插件'

+1

要調用otherFunc它會是$(div).mynamespace.otherFunc(); ? – Chris 2011-02-01 01:16:45

+1

請注意這一點。聰明的回答,但行爲更像是[裝飾模式](http://en.wikipedia.org/wiki/Decorator_pattern)比命名空間。如果您不熟悉該模式的正常利弊,那可能會讓您陷入麻煩。 – colllin 2013-02-26 20:55:52

2

我知道這是個老問題了......但是,如果只需將.替換爲_,爲什麼要編寫所有這些額外的代碼呢?

$.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!'); } 
+0

這會影響命名空間,並且看起來並不好。 – WhyNotHugo 2012-07-23 21:22:07

+0

清爽務實。謝謝! – colllin 2013-02-26 05:43:47

12

我知道我差不多三年晚了,但希望這個問題的未來讀者能從我的回答中受益。 GSto從jQuery插件設計的角度看起來很不錯,但有一個小問題:調用mynamespace()用新方法調用返回的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's Advanced JavaScript tutorial是很好解釋的,但嚴格意義上是什麼在發生的例子是這樣的:

milosz(內部$.fn[namespaceName])被調用,this指向jQuery實例返回b y $('.mydiv')。因此,if聲明落入else塊,並調用構造函數版本milosz(由於原因即將變得明顯,因此在內部引用爲executor)。構造函數傳遞一個參數:this,指向jQuery實例的指針,該實例將作爲milosz名稱空間的所有成員的執行上下文。我們回到if聲明中,這次執行第一個塊,其中傳入的jQuery實例存儲在名爲__context__(希望被覆蓋的可能性很低)的成員變量中。返回構造的對象,並完成對原始jQuery實例的引用,並通過調用$.namespace將其添加到其原型的任何包裝器。這些包裝只是執行傳遞到milosz名稱空間的方法,並將原始jQuery對象作爲上下文執行,如執行redify時發生的那樣。

嗯,我知道這是一口,無論如何,它的作用就像接受的答案,但看起來像jQueryish的答案,這對我來說是兩全其美。

+1

偉大的方法,感謝一年後,在黨後三年。 – cmsjr 2012-10-18 16:45:05

+1

我將在我的新jQuery插件工廠庫中使用這種技術。讓我的頭受傷,但它的效果! – 2013-05-24 19:02:20

+0

我知道它已經有一段時間了,但是這種方法不允許我調用函數作爲$ .myNamespace()。function() - 但它的作用是$()。myNamespace()。function() - 任何人都有對此的解決方案? – 2014-05-14 01:54:13

1
$.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. 
+0

這個問題是,函數將不會收到'this'上下文中的jQuery選擇器。 – 2015-12-30 11:46:24