jQuery插件命名空间

Mot*_*ika 26 jquery

如何创建一个jQuery插件,以便我可以在我的插件中使用命名空间?

$("#id1").amtec.foo1();
$("#id1").amtec.foo2();
Run Code Online (Sandbox Code Playgroud)

这些似乎都不起作用.

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

    })(jQuery);
Run Code Online (Sandbox Code Playgroud)
(function($) {
    $.fn.amtec = function(){
        var foo1 = function(){ return this.each(function(){}); };
        var foo2 = function(){ return this.each(function(){}); };
        }
    })(jQuery);
Run Code Online (Sandbox Code Playgroud)

Ale*_*hev 21

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

            foo2: function(){
                return jq.each(function(){});
           }
       }
    };
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢亚历山大!它确实有效,但是作为$("#id1").amtec().foo1(); 而不是$("#id1").amtec.foo2(); (4认同)

Mil*_*osz 15

我知道我已经差不多三年了,但希望这个问题的未来读者可以从我的答案中受益.从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
Run Code Online (Sandbox Code Playgroud)

选择的答案没有这个问题,因为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);
Run Code Online (Sandbox Code Playgroud)

用法示例:

$.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
Run Code Online (Sandbox Code Playgroud)

该代码使用了一些非常低级的JavaScript细节,这些细节由John Resig的高级JavaScript教程很好地解释,但是松散地说这个例子中发生的事情是:

milosz(内部$.fn[namespaceName])被调用时,this指向jQuery被返回的实例$('.mydiv').因此,if语句落到else块中,并且milosz调用构造函数版本(内部引用executor,原因即将变得明显).构造函数传递一个参数:this,一个指向jQuery该实例的指针,该实例将成为milosz命名空间的所有成员的执行上下文.我们回到if语句中,这次执行第一个块,其中传入的jQuery实例存储在一个被调用的成员变量中__context__(希望被覆盖的可能性很小).返回构造的对象,完成对原始jQuery实例的引用以及通过调用添加到其原型的任何包装器$.namespace.这些包装器只是执行传递给milosz命名空间的方法,原始jQuery对象作为上下文,就像redify执行时一样.

呸,我知道它是满口的,无论如何,重点是它的工作方式就像接受的答案,但看起来像是jQueryish的答案,对我来说这是两个世界中最好的.

  • 如何从插件中调用的方法返回值?它返回undefined给我http://jsfiddle.net/h86brjrn/ (2认同)