Пользователь
0,0
рейтинг
17 ноября 2012 в 19:25

Разработка → Пишем плагин для jQuery перевод tutorial

Эта статья призвана дать представление об основных правилах, подходах, дающих наилучшие результаты, и распространённых ошибках, на которые стоит обратить внимание при разработке плагинов для jQuery.


Приступая к работе


Сперва создаём новое свойство-функцию для объекта jQuery, где именем нового свойства будет имя нашего плагина:

jQuery.fn.myPlugin = function() {

  // Тут пишем функционал нашего плагина

};

Но постойте, где-же привычный нам значок доллара, который мы все хорошо знаем? Он всё ещё здесь, а чтобы он не конфликтовал с другими библиотеками, которые тоже могут использовать символ доллара, рекомендуется «обернуть» объект jQuery в непосредственно выполняемую функцию-выражение (IIFE, Immediately Invoked Function Expression), которое связывает объект jQuery с символом "$", чтобы он не был переопределён другой библиотекой во время выполнения.

(function( $ ) {
  $.fn.myPlugin = function() {
  
      // Тут пишем функционал нашего плагина

  };
})(jQuery);

Так лучше. Теперь внутри этого замыкания (closure), мы можем использовать знак доллара как нам заблагорассудится.

Контекст


Теперь у нас есть оболочка, внутри которой мы можем начать писать код плагина. Но прежде чем мы начнём, я хотел бы сказать несколько слов о контексте. В непосредственной области видимости функции нашего плагина ключевое слово «this» ссылается на объект jQuery, для которого был вызван этот плагин.

И тут часто ошибаются, полагая, что в других вызовах, где jQuery принимает callback-функцию, «this» указывает на элемент DOM-дерева. Что, в свою очередь, приводит к тому, что разработчики дополнительно оборачивают «this» в функцию jQuery.

(function( $ ){

  $.fn.myPlugin = function() {
  
    // нет необходимости писать $(this), так как "this" - это уже объект jQuery
    // выражение $(this) будет эквивалентно $($('#element'));
      
    this.fadeIn('normal', function(){

      // тут "this" - это элемент дерева DOM

    });

  };
})( jQuery );

    $('#element').myPlugin();

Основы


Теперь, когда мы понимаем как работать с контекстом, напишем плагин jQuery, который выполняет полезную работу.

(function( $ ){

  $.fn.maxHeight = function() {
  
    var max = 0;

    this.each(function() {
      max = Math.max( max, $(this).height() );
    });

    return max;
  };
})( jQuery );


var tallest = $('div').maxHeight(); // Возвращает высоту самого высокого div-а

Это простой плагин, который, используя .height(), возвращает нам высоту самого высокого div-а на странице.

Поддерживаем возможность цепочек вызовов


Предыдущий пример рассчитывает и возвращает целочисленное значение наиболее высокого div-а на странице. Обычно, плагин модифицирует набор элементов дерева DOM, и передает их дальше, следующему методу в цепочке вызовов. В этом заключается красота jQuery и одна из причин его популярности. Итак, чтобы ваш плагин поддерживал цепочки вызовов, убедитесь в том, что ваш плагин возвращает this.

(function( $ ){

  $.fn.lockDimensions = function( type ) {  

    return this.each(function() {

      var $this = $(this);

      if ( !type || type == 'width' ) {
        $this.width( $this.width() );
      }

      if ( !type || type == 'height' ) {
        $this.height( $this.height() );
      }

    });

  };
})( jQuery );

$('div').lockDimensions('width').css('color', 'red');

Так как плагин возвращает this в своей непосредственной области видимости, следовательно он поддерживает цепочки вызовов, и коллекция jQuery может продолжать обрабатываться методами jQuery, например, такими как .css.
И, если ваш плагин не должен возвращать никакого рассчитанного значения, вы должны всегда возвращать this в непосредственной области видимости функции плагина. Аргументы, которые передаются в плагин при вызове, передаются в непосредственную область видимости функции плагина. Так, в предыдущем примере, строка 'width' является значением параметра «type» для функции плагина.

Настройки и умолчания


Для более сложных и настраиваемых плагинов, предоставляющих большое количество возможностей настройки лучше иметь настройки по-умолчанию, которые расширяются (с помощью $.extend) во время вызова плагина.

Так вместо вызова плагина с большим количеством параметром, вы можете вызвать его с одним параметром, являющимся объектным литералом настроек, которые вы хотите расширить. Например, вы можете сделать так:

(function( $ ){

  $.fn.tooltip = function( options ) {  

    // Создаём настройки по-умолчанию, расширяя их с помощью параметров, которые были переданы
    var settings = $.extend( {
      'location'         : 'top',
      'background-color' : 'blue'
    }, options);

    return this.each(function() {        

      // Тут пишем код плагина tooltip

    });

  };
})( jQuery );

$('div').tooltip({
  'location' : 'left'
});

В этом примере после вызова плагина tooltip с указанными параметрами, значение параметра местоположения ('location')
переопределяется значением 'left', в то время, когда значение параметра 'background-color' остаётся равным 'blue'. И в итоге объект settings содержит следующие значения:

{
  'location'         : 'left',
  'background-color' : 'blue'
}

Это хороший способ создавать гибко-настраиваемые плагины без необходимости определять каждый из доступных параметров настройки.

Определение пространства имён


Корректное определение пространства имён для плагина очень важно и обеспечивает достаточно низкую вероятность переопределения другим плагином или кодом, выполняющимся на той-же странице. Вдобавок определение пространства имён упрощает разработку, так как упрощается отслеживание нужных методов, событий и данных.

Методы плагина

При любых обстоятельствах один плагин должен определять не более одного пространства имён для объекта jQuery.fn.

(function( $ ){

  $.fn.tooltip = function( options ) { 
    // НЕ НАДО
  };
  $.fn.tooltipShow = function( ) {
    // ТАК
  };
  $.fn.tooltipHide = function( ) { 
    // ДЕЛАТЬ
  };
  $.fn.tooltipUpdate = function( content ) { 
    // !!!  
  };

})( jQuery );

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

(function( $ ){

  var methods = {
    init : function( options ) { 
      // А ВОТ ЭТОТ
    },
    show : function( ) {
      // ПОДХОД
    },
    hide : function( ) {
      // ПРАВИЛЬНЫЙ
    },
    update : function( content ) {
      // !!!
    }
  };

  $.fn.tooltip = function( method ) {
    
    // логика вызова метода
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Метод с именем ' +  method + ' не существует для jQuery.tooltip' );
    } 
  };

})( jQuery );

// вызывает метод init
$('div').tooltip(); 

// вызывает метод init
$('div').tooltip({
  foo : 'bar'
});

// вызывает метод hide
$('div').tooltip('hide'); 

// вызывает метод update
$('div').tooltip('update', 'Теперь тут новое содержимое'); 

Этот тип архитектуры плагинов позволяет вам инкапсулировать все ваши методы в родительском по отношению к плагину замыкании (closure), и вызывать их, сперва передавая имя метода как строку, а затем передавая любые дополнительные параметры для этого метода. Этот подход к инкапсуляции методов является стандартом в сообществе разработчиков jQuery-плагинов и применяется в бесчисленном множестве плагинов и виджетов в jQueryUI.

События

Малоизвестная особенность метода bind заключается в том, что он позволяет определять пространства имён для связанных событий. Если ваш плагин связывает некую функциональность с каким-нибудь событием, то хорошим тоном будет задать пространство имён для этого события. И если позднее вам потребуется отвязать эту функциональность от события, то вы сможете это сделать, не затрагивая функциональность, которая может быть прикреплена к этому-же типу события.

Вы можете определить пространство имён для ваших событий, просто добавив точку и название пространства имён к названию типа события, с которым вы связываетесь.

(function( $ ){

  var methods = {
     init : function( options ) {

       return this.each(function(){
         $(window).bind('resize.tooltip', methods.reposition);
       });

     },
     destroy : function( ) {

       return this.each(function(){
         $(window).unbind('.tooltip');
       })

     },
     reposition : function( ) { 
       // ... 
     },
     show : function( ) { 
       // ... 
     },
     hide : function( ) {
       // ... 
     },
     update : function( content ) { 
       // ...
     }
  };

  $.fn.tooltip = function( method ) {
    
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Метод с именем ' +  method + ' не существует для jQuery.tooltip' );
    }    
  
  };

})( jQuery );

$('#fun').tooltip();
// Некоторое время спустя...
$('#fun').tooltip('destroy');

В этом примере, когда плагин tooltip проинициализировался с помощью метода init, он связывает метод reposition с событием resize (изменение размеров) окна, с указанием пространства имён 'tooltip'. Позднее, когда разработчик намерен разрушить объект tooltip, он может отвязать все прикреплённые к плагину обработчики путём указания соответствующего пространства имён. В данном случае — 'tooltip' для метода unbind. Это позволяет безопасно отвязать обработчики от событий без риска случайно отвязать событие, связанное с обработчиком вне данного плагина.

Данные

Зачастую во время разработки плагинов, вы можете столкнуться с необходимостью сохранения состояний или проверки, был-ли плагин уже проинициализирован для указанного элемента. Использование метода data из jQuery — это хороший способ отслеживать состояние переменных для каждого элемента. Однако вместо того, чтобы отслеживать множество отдельных вызовов data с разными именами, рекомендуется использовать один объектный литерал, который будет объединять все ваши переменные под одной крышей и вы будете обращаться к этому объекту через одно пространство имён.

(function( $ ){

  var methods = {
     init : function( options ) {

       return this.each(function(){
         
         var $this = $(this),
             data = $this.data('tooltip'),
             tooltip = $('<div />', {
               text : $this.attr('title')
             });
         
         // Если плагин ещё не проинициализирован
         if ( ! data ) {
         
           /*
            * Тут выполняем инициализацию
           */

           $(this).data('tooltip', {
               target : $this,
               tooltip : tooltip
           });

         }
       });
     },
     destroy : function( ) {

       return this.each(function(){

         var $this = $(this),
             data = $this.data('tooltip');

         // пространства имён рулят!!11
         $(window).unbind('.tooltip');
         data.tooltip.remove();
         $this.removeData('tooltip');

       })

     },
     reposition : function( ) { // ... },
     show : function( ) { // ... },
     hide : function( ) { // ... },
     update : function( content ) { // ...}
  };

  $.fn.tooltip = function( method ) {
    
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Метод с именем ' +  method + ' не существует для jQuery.tooltip' );
    }    
  
  };

})( jQuery );

Использование data позволяет отслеживать состояние переменных между вызовами вашего плагина. Определение пространства имён для data в одном объектном литерале, обеспечивает, как простой централизованный доступ к свойствам плагина, так и сокращает пространство имён data, что позволяет просто удалять ненужные данные по мере необходимости.

Заключение и полезные советы


Создание плагинов для jQuery позволяет извлечь максимальную пользу из этой библиотеки и абстрагировать свои наиболее удачные решения и часто используемые функции в повторно используемый код, который может сохранить вам время и сделает процесс разработки более эффективным. Ниже представлена краткая выдержка того, что следует помнить во время разработки своего jQuery плагина:

  • Всегда оборачивайте свой плагин в конструкцию:

               (function( $ ){ 
                          /* тут пишем код плагина */ 
                })( jQuery );
    

    Примечание переводчика: в оригинальной статье эта синтаксическая конструкция названа замыканием (closure), но это не замыкание, а непосредственно вызываемая функция (IIFE).

  • В непосредственной области выполнения функции вашего плагина не оборачивайте this в ненужные синтаксические конструкции.
  • Если только вы не возвращаете из функции плагина какое-то определенное значение, всегда возвращайте ссылку на this для поддержки цепочек вызовов.
  • При необходимости передачи длинного списка параметров, передайте настройки вашего плагина в виде объектного литерала, значения которого будут распространятся на значения по-умолчанию для параметров вашего плагина.
  • Для одного плагина определяйте не более одного пространства имён jQuery.fn.
  • Всегда определяйте пространство имён для ваших методов, событий и данных.
Перевод: John Resig
Rafael Osipov @Rafael
карма
125,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (67)

  • –5
    Извините, но это настолько элементарно…

    UPD. Заметил, что это перевод статьи Джона Resig-а — в таком случае это не первый, не второй и даже не третий перевод. Об этом уже столько раз писали…
    • +26
      Элементарно для кого, простите? К примеру, я раньше не писал плагинов для jQuery. И, думаю, тут много людей, которые не обладают опытом написания плагинов, но интересуются этой темой.
      • +21
        Я имел в виду, что в инете существует огромное количество инфы на эту тему. И на русском тоже. Да хотя бы:

        anton.shevchuk.name/javascript/jquery-for-beginners-write-plugins/
        www.linkexchanger.su/2008/67.html
        xdan.ru/Kak-napisat-plagin-na-jQuery.html
        jquerylist.ru/tutorials/writing-your-own-plugins.html
        blog.alexxxnf.ru/post/34/
        jquery.page2page.ru/index.php5/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0_jQuery
        www.wisdomweb.ru/JQ/plugin.php
        jdrupal.ru/node/30

        Дальше мне лень было добавлять. Вбейте в любой поисковик «как написать плагин jquery»
        • +2
          Как вы можете заметить, на настоящий момент, пятьдесят с лишним человек нашли эту статью полезной для себя.
          • –2
            И из них плюсанули 7 человек.
            • +1
              Продолжайте, и?
              • +8
                … и вы в очередной раз пишите, как раскрасить белое белым, а черное — черным. Топики про плагины к jQuery настолько унылы, что их даже обсуждать тоскливо.

                — «Зацените, я научился ЭТО делать!».
                — «Держи нас в курсе»…
                • 0
                  Топики про плагины к jQuery настолько унылы, что их даже обсуждать тоскливо.


                  Искренне благодарю вас за то, что переступили через себя, Азиз.

                  — «Зацените, я научился ЭТО делать!».
                  — «Держи нас в курсе»…


                  Если вы воспринимаете справочную статью как попытку хваствовства, то это проекции вашего бессознательного. Но спасибо за хорошее настроение :)
                  • +3
                    Но простите, на обучение это тоже не тянет. Да, какие-то банальные вещи разрозненные по статьям собраны худо бедно в одном месте. Да пост на хабре. В целом же достаточно было бы сконцентрироваться на мелочах и статья вышла бы уже обучающего характера.

                    Скажем… про то что each лучше не использовать, в случае если планируется применять плагин для сравнительно больших коллекций элементов (скажем какой-то фикс стилей, не знаю, всякое может быть).

                    Ну и там особенности тестирования, сборки плагинов через grunt, хитрости архитектуры, какие-то best practices. А это… ну так… очередная статья из цикла «jQuery для чайника», коих даже по этой теме пруд пруди.
                    • –1
                      Ну как вам сказать, для вас эта статья не тянет на обучающую. Для меня — тянет. Для других тоже.
                      Не всех, конечно. Некоторые особенно нервно реагируют, как я могу заметить.

                      Следуя их логике следовало ввергнуть в геенну огненную все переводные статьи в стиле «50 удобных инструментов для вебмастеров». Но, как можете заметить, такие статьи принимаются благосклонно.

                      А почему? Потому что они полезны. Да их можно найти гуглем и даже без перевода разобраться. Благо Google Chrome предлагает автоматический перевод, который позволяет не растеряться на странице. Чего, в данном случае, достаточно.

                      Но перевод их и публикация на хабре делают удобным работу с этим материалом.

                      Переводов в рунете много, согласен. Но мне было проще перевести эту статью, чем продираться через некачественные переводы, SEO-сайты, фильтровать откровенный шлак и выбирать подходящий перевод.

                      Если кто-то опубликует тут статью для начинающих о том, как работать с IBM Lotus Notes/Domino и как писать программы для этой системы, то я поблагодарю его, несмотря на сотни качественных переводных статей на ibm.developerworks.

                      Да, для меня это будут азы, над которыми я ломал голову много лет назад, разбираясь с вопросом. Но с моей точки зрения это будет полезный обучающий материал для тех, кто пока не так опытен.
                      • +1
                        Просто самый банальный пример плагина можно получив просто выполнив команду grunt init:jquery. Причем не просто какой-то там, а с юнит тестами, с минификацией сконкатенированного файла (в случае если проект разбит на файлы) ну и т.д.

                        Мое мнение, что если человек не знает что такое контекст, или область видимости, то ему не стоит писать плагины для jQuery, ибо потом видешь это ужасающее разнообразие очень посредственных плагинов.
                    • 0
                      Посоветуйте пожалуйста ссылки на подобные статьи.
          • +1
            За популяризацию спасибо, плюсанул.

            Но чаще тут добавляют в избранное затем чтобы «прочесть потом, когда-нибудь», т.е. скорее показатель того что заголовок интересный, но много букв.
        • 0
          А это вы и не заметили :) habrahabr.ru/post/153099/
        • 0
          Позволю себе спустя пару лет, вставить свои пять копеек. На сегодняшний день эта статья первая в выдаче Гугла по запросу «создание jquery плагина». Так, что полезность неоспорима, учитывая, что бегло пробежавшись по статье, её оценке и комментах — можно оценить полезность или вредность информации.
          • 0
            Необычно спустя пару лет читать свои комментарии :).

            И думаю, всё же гораздо полезнее было бы, если бы автор переводил что-то ещё не переведённое.
      • +4
        Про элементарность — имел в виду, что некоторые конструкции, про которые вы рассказываете, элементарны. Например, вот эта:
        var settings = $.extend(defaults, options);

        Или вот эта:
        (function( $ ){ })( jQuery );
        Кстати вы даже не объяснили, зачем это замыкание нужно. Так что дополню: чтобы внутри можно было объявлять переменные (и они не выскакивали в глобальное окружение), а передача аргументов объекта jQuery — это страховка от jQuery.noConflict(). Не помешает также переделать вот так вот:
        (function( $, undefined ){ })( jQuery );

        Чтобы подстраховаться от определения внешней переменной undefined.
        • –3
          На полноту и всеохватность данный перевод не претендовал. Это всего-лишь перевод одной из статей с jquery.com.

          Я отдаю себе отчёт в том, что это базовые понятия. Но они элементарны не для всех.
          Вы, насколько я понимаю, давно и плотно работаете с javascript. Но ведь есть люди и с другим опытом. И то, что элементарно для вас, совсем не очевидно для меня, например. И наоборот.

          Для меня эта статья не была элементарной. И в процессе её перевода я разобрался и понял как что работает.
          И, думаю, что этот перевод принесет пользу и другим, кто интересуется jQuery.

          И этот факт главнее, чем то, что кто-то скажет «это элементарно».

          Я так думаю.
          • 0
            Вы правы
            • –1
              Я ведь не спорю с вами, Дмитрий. Лишь стараюсь объяснить свою точку зрения.
              • 0
                Спор — это и есть доказывание своей точки зрения.
                Так что я тоже не спорю :)
        • 0
          (function( $, undefined ){ })( jQuery );
          

          Такой трюк, несомненно, имеет плюсы, но и минусы тоже: некоторые IDE ругаются, если количество передаваемых параметров не соответствует количеству объявленных. Предпочтительнее поступать так:
          (function( $ ){
            var undefined;
           })( jQuery );
          


          И даже не так:
          var undefined = void 0;
          

          , ибо на это ругается JSLint.
          • 0
            Как вариант
            (function( $, undefined){
              var undefined;
             })( jQuery, (function())());
            

            Хотя не знаю будет ли кто-то ругаться на это.
            Используется идея, что функция без return'a возвращает undefined.
            • 0
              В вашем варианте получается, что аргумент undefined будет переписан переменной undefined. Т.е. всё было сделано зря и результат будет эквивалентен тому, что я написал выше.

              Ну и на это ругается IDEA, так как бессмысленно объявлять аргумент, если в теле функции есть одноименная переменная.
          • +2
            Я считаю, что это валидный JS-код и это проблема IDE
            • 0
              Если необходимо использовать несколько вариантов передачи аргументов, есть выход:

              1. Принимать один аргумент — объект и проверять его свойства.
              2. Не указывать явно имена аргументов в функции, а использовать arguments.

              Ну и этот код:
              function fnc(foo, bar) {
                if (bar === undefined) {}
              }
              

              потенциально бажный. Зависит от конкретной ситуации.
          • 0
            Зачем, кстати, вам этот undefined? typeof blabla === "undefined" же. Только не говорите, что экономия N байт.
            • 0
              Минификаторы на основе замыканий тогда жмут чуточку лучше.
              • +1
                Минификаторы должны такие ситуации отслеживать и заменять мои длинные инструкции аналогичными короткими. Все мы должны писать более читаемо и единообразно (у каждого понимание свое) и не подстраиваться под IDE и под глупый минификатор :)
                if (typeof pewpew === "undefined") {} // почти не изменится
                
                if(typeof pewpew=="undefined") {}
                
                //--
                
                var a;
                if (typeof a === "undefined") {} // изменится сильно
                
                var a, u;
                if(a==u){}
                
                • 0
                  Жаль разработчики IDE и минификаторов об этом не знают:)
                • 0
                  Я не стану пользоваться минификаторами, которые меняют конструкции кода не спросив меня.
                  • 0
                    Да они сплошь и рядом. Для остального есть Source Map.
                    • 0
                      Изменения которые делает аглифи не сказываются на логике. В то же время поведение при typeof немного отличается от банального сравнения.
                      • 0
                        Предъявите, пожалуйста, хотя бы один случай, когда вот эта замена не будет корректна:

                        function A(a) {
                            if (typeof a === "undefined") {
                                return "0";
                            }
                        }
                        
                        // after
                        function A(a){var u;return a===u?0:u}
                        

                        • 0
                          В приведенном вами случае никак не поменяется. а в случае
                          (function(){
                              if (typeof a != 'undefined') {
                              ...
                              }
                          })();
                          

                          думаю кое что произойдет.

                          Хотя вы уже об этом говорили. Это я не внимательный.
                          • 0
                            На то и нужен «умный» минификатор, а не замена по RegExp :) Благо у функций в JavaScript скоуп без eval всегда стабильный — осюда и возможны такие рискованные оптимизации.
                • +1
                  "==" медленнее же чем "==="
            • +1
              Ну я не говорил, что он мне нужен, но раз вы хотите знать моё мнение, то:

              1. Мне проще воспринимать запись
              blabla === undefined
              

              чем
              typeof blabla === "undefined"
              

              Зачем лишний оператор — не понятно.

              2. Когда я пишу плагин/виджет для проекта, окружение которого я не контролирую, мне проще перестраховаться и вписать-таки эту переменную, чем потом разгребать баг-репорты. Может я параноик, не знаю.
  • +4
    Вбейти в гугл jquery plugin, первая же ссылка ведет на оффициальную документацию где все подробно написано.
    • –5
      Я так и поступил.

      Но на русском читать документацию мне удобнее, чем на английском.
  • –3
    У меня планины на jQuery почему-то всегда писались по 2 раза. Сначало оно просто работало, но я не понимал как. А потом это рефакторилось и… получалось нечто велосипедное. Я подумал, что велосипед уже написали до меня. Теперь я пишу на Backbone с первого раза.
    • +3
      Захватывающая история. Каким образом Backbone связан с jQuery плагином?
  • +1
    Если человек хотя бы прочитает этот простой учебник по js learn.javascript.ru/ то ему не понадобятся, подобные посты и много других (о js) которые иногда проскакивают на хабре.
    • –2
      Должен заметить, что я рад за этого человека.

      Перефразируя ваш комментарий, можно сказать, что если человек хотя бы раз прочтёт учебник по линейной алгебре, то ему не понадобится читать этот перевод и много других статей с формулами, которые есть в учебниках, и которые иногда проскакивают на хабре. Некоторые так и считают, как вы можете заметить из комментариев к вышеприведенной ссылке. А мне удобнее работать с материалом именно так. И не только мне одному.

      И раз этот перевод может быть кому-то полезен, то пусть он будет здесь.
      • +2
        Это немного разные вещи, У примеру:
        Что бы писать на языке нужно его понимать, иначе получается индусский код.
        Что бы воспользоваться математической формулой не обязательно читать целую книгу.
    • +1
      Не сказал бы, что он простой. Просто для работы с ним достаточно минимальных знаний в программировании вообще. При этом, ближе к концу там разбираются вполне себе комплексные задачи.

      P.S.
      Именно с этого учебника началось моё серьёзное знакомство с js. Сейчас читаю Javascript patterns и говорю спасибо Илье Кантору за прекрасный learn.javascript.ru.
      • 0
        До этого учебника сам писал ужаснейший код и думал «нафиг те книги», но после прочтения этой книги полностью поменял свое мнение.
        Спасибо Илье Кантору.
  • +1
    Давно мучает вопрос: почему в jQuery принят такой долбанутый способ вызовов методов?

    Почему названия методов строчками
    $('tag').fooPlugin('barMethod', bazArg)
    а не традиционно функционально
    $('tag').fooPlugin.barMethod(bazArg)
    ?

    Где логика?
    • –1
      Не ищите логики там, где её изначально нет )
    • 0
      Говорят, чтобы можно было таким образом отделить приватные ( _имяМетода ) методы от публичных ( имяМетода ).
      • +1
        А зачем иметь возможность из вне вызывать приватные методы? На то они и приватные.
        • +1
          Там стоит проверка — что если метод начинается с подчеркивания "_", то такой метод нельзя вызывать. Так что, вы правы, возможности вызывать приватные методы извне — нет.
          • +1
            Спасибо за разъяснение.
    • 0
      Обычно люди по разному делают. Видел много вариантов вызовов методов. Мне больше всех понравился такой:
      var somePluginInstance = $('.selector').SomePlugin().data('SomePlugin');
      ....
      somePluginInstance.doSomeAction();
      


      Вообще на вкус и цвет, как говориться.
      • 0
        Это ж религиозно неверным считается. Вон, в Yii что-то вроде этого было, так авторов помидорами закидали: «Ка-а-ак! Плагин jQuery и с таким неправильным синтаксисом! LRN2CODE N00B!» Вроде, во второй версии переписывать собирались.
    • 0
      Второй подход вносит хаос в привычный вид цепочности вызовов методов jQuery.
      • 0
        «Строчковые» методы вносят больше хаоса, ИМХО.

        И если уж так именно функции в цепочке нужны, то можно писать $('tag').fooPlugin().barMethod(bazArg)
        • 0
          Имеется ввиду что после вызова fooPlugin должен возвращаться массив эллементов, а не что-то от плагина. Опять же, я обычно выношу все в Data секцию и не парюсь.
  • 0
    Ещё бы пример правильного наследования jquery-плагинов.
    • 0
      Что вы имеете в виду?
      • 0
        Хочется разработать свой плагин на базе уже готового, задача в том, как сделать это наиболее простым и сопровождаемым образом.
        • 0
          Тут все очень и очень сильно зависит от реализации плагина. 90% плагинов, нутро которых я ковырял, просто невозможно безболезненно расширить. Даже больше скажу, на исходники половины из них без слез смотреть нельзя.
  • 0
    Спасибо большое. Это первая статья в гугле по запросу «как создавать плагины jquery» и она всё расставила по своим местам в моей голове :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.