Как сделать плагин JQuery расширяемым?

Я пытаюсь перенести некоторые общие действия, специфичные для приложения, в плагин jQuery следующим образом:

$.fn.extpoint = function() {...}

Но я не хочу объявлять несколько точек расширения:

$.fn.extpoint1 = function() {...}
$.fn.extpoint2 = function() {...}
...

Вместо этого я хотел бы использовать синтаксический сахар, например:

$("#id").extpoint.func1().extpoint.func2()

С определением:

$.fn.extpoint = {}
$.fn.extpoint.func1 = function() {
    this.val();
    this.data("ip");
    ...
    return this;
}

и позвоните:

$("#id").extpoint.func1(...)

this указывает на $.fn.extpoint (словарь с элементами func1, func2,...) вместо исходного объекта jQuery, когда оценивается func1.

Можно ли сделать подключаемый модуль jQuery расширяемым?

ПС. Можно передать имя функции в качестве первого аргумента $.fn.extpoint и реализовать вызов $.fn.extpoint('extend', func) для расширения (сохранения во внутреннем словаре связи между именами и реализациями) точки расширения. В этом случае варианты использования выглядят так:

$("#id").extpoint('func1', ...).extpoint('func2', ...)

но я ищу способ сделать больше синтаксического сахара...


person gavenkoa    schedule 13.03.2013    source источник
comment
Это не сработает следующим образом: $("#id").extpoint.func1().extpoint.func2(), потому что func1 и func2 не будут иметь доступа к $("#id")   -  person Kevin B    schedule 13.03.2013
comment
@KevinB Да, понятно, но поищи способ избежать этого с помощью каких-то неизвестных уловок... +1   -  person gavenkoa    schedule 13.03.2013
comment
Год или два назад на форумах jQuery был пост, где кто-то придумал, как это работает, но это было очень сложно, и я не могу точно вспомнить, как это было сделано. Советую поискать там, не могу найти.   -  person Kevin B    schedule 13.03.2013
comment
Кажется, я нашел ветку, которую вы упомянули: groups.google.com/group/jquery -dev/browse_thread/thread/.   -  person gavenkoa    schedule 13.03.2013
comment
Пример рабочего кода по адресу: code.google. .com/p/jquery-plugin-dev/source/browse/trunk/   -  person gavenkoa    schedule 13.03.2013


Ответы (2)


Задача, которую я прошу, трудновыполнима.

Официальные документы говорят:

Ни при каких обстоятельствах один подключаемый модуль не должен требовать более одного пространства имен в jQuery.fn объекте:

(function( $ ){
  $.fn.tooltip = function( options ) { 
    // THIS
  };
  $.fn.tooltipShow = function( ) {
   // IS
  };
  $.fn.tooltipHide = function( ) { 
    // BAD
  };
})( jQuery );

Это не рекомендуется, потому что это загромождает пространство имен $.fn. Чтобы исправить это, вы должны собрать все методы вашего плагина в литерал объекта и вызвать их, передав подключаемому модулю строковое имя метода.

Другой подход — сохранить ссылку на this, как в http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js

Итак, ваши звонки выглядят так:

$.fn.addPlugin('test2', {
    __construct : function(alertText) { alert(alertText); },
    alertAttr   : function(attr) { alert($(this).attr(attr)); return this; },
    alertText   : function() { alert($(this).text()); return this; }
});

$('#test2').bind('click', function() {
     var btn = $(this);

     btn.test2('constructing...').alertAttr('id').alertText().jQuery.text('clicked!');

     setTimeout(function() {
             btn.text('test2');
     }, 1000);
});

Некоторые связанные ссылки:

Расширение плагина старого стиля:

person gavenkoa    schedule 13.03.2013

Здесь представлен обзор создания плагина. Я считаю, что то, о чем вы спрашиваете, называется «цепочкой». Это то, что делает jQuery таким простым в использовании, и хорошо, что вы хотите убедиться, что реализуете его правильно.

Главное, что нужно помнить при разработке вашего плагина в отношении цепочки, — это всегда return this; из ваших методов. Это то, что позволит вам сохранить цепочку.

person BinaryTox1n    schedule 13.03.2013
comment
Извините, я не говорю о цепочке. Но насчет того, чтобы сделать подключаемый модуль jQuery совместимым образом расширяемым, как и сам jQuery... - person gavenkoa; 13.03.2013