Пространство имен плагинов jQuery - PullRequest
25 голосов
/ 08 октября 2009

Как мне создать плагин 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 ]

21 голосов
/ 08 октября 2009
(function($) {
    $.fn.amtec = function () {
        var jq = this;
        return {
            foo1: function(){
                return jq.each(function(){});
            },

            foo2: function(){
                return jq.each(function(){});
           }
       }
    };
})(jQuery);
14 голосов
/ 12 июля 2012

Я знаю, что почти три года опаздываю на вечеринку, но, надеюсь, будущие читатели этого вопроса могут получить пользу от моего ответа. Ответ 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, которые хорошо объяснены Расширенным руководством Джона Резига по JavaScript , но в общих чертах то, что происходит в примере, таково:

Когда вызывается milosz (внутренне $.fn[namespaceName]), this указывает на экземпляр jQuery, возвращаемый $('.mydiv'). Следовательно, оператор if переходит к блоку else, и вызывается версия конструктора milosz (именуемая внутри executor по причинам, которые скоро станут очевидными). В конструктор передается единственный параметр: this, указатель на jQuery экземпляр, который будет контекстом выполнения для всех членов пространства имен milosz. Мы входим обратно в оператор if, на этот раз выполняя первый блок, в котором переданный экземпляр jQuery сохраняется в переменной-члене с именем __context__ (которая, вероятно, имеет низкий шанс перезаписи). Созданный объект возвращается со ссылкой на исходный экземпляр jQuery и любые обертки, добавленные к его прототипу с помощью вызовов $.namespace. Эти оболочки просто выполняют методы, переданные в пространство имен milosz с исходным объектом jQuery в качестве контекста, как это происходит при выполнении redify.

Бах, я знаю, что это глоток, в любом случае дело в том, что он работает как принятый ответ, но выглядит как ответ jQueryish, который для меня является лучшим из обоих миров.

3 голосов
/ 08 октября 2009
(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

plugin ', затем сбрасывается к обычному jquery и оповещает' plugin '

2 голосов
/ 13 июня 2012

Я знаю, что это старый вопрос ... Но зачем писать весь этот дополнительный код, когда вы можете просто заменить . на _?

$.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!'); }
1 голос
/ 05 октября 2014
 $.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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...