jQuery插件命名空间

时间:2009-10-08 13:37:46

标签: 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);

5 个答案:

答案 0 :(得分:21)

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

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

答案 1 :(得分:14)

我知道我差不多已经晚了三年,但希望这个问题的未来读者可以从我的答案中受益。从{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

代码使用了John Resig's Advanced JavaScript tutorial很好解释的JavaScript的一些非常低级别的细节,但是松散地说这个例子中发生的是:

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

Bah,我知道它是满口的,无论如何,重点是它的工作方式与接受的答案相似,但看起来像是jQueryish的答案,对我来说这是两全其美的。

答案 2 :(得分: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并提醒'插件'

答案 3 :(得分: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!'); }

答案 4 :(得分: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.