Статьи

jQuery кратко: плагины jQuery

При написании плагина jQuery должна быть реализована та же процедура предотвращения конфликтов, что и в обычном старом коде jQuery. Имея это в виду, все плагины должны содержаться в закрытой области видимости, где $ alias может использоваться без опасения конфликтов или неожиданных результатов.

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

01
02
03
04
05
06
07
08
09
10
11
12
<!DOCTYPE html>
<html lang=»en»>
<body>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> alert(jQuery(document).jquery);
        // Don’t use $ here.
        (function ($) {
            // Can use $ without fear of conflicts
            alert($(document).jquery);
        })(jQuery);
</body>
</html>

Новые плагины присоединяются к объекту jQuery.fn , так как это ярлык или псевдоним для jQuery.prototype . В нашем примере кодирования ниже мы добавляем плагин count к объекту jQuery.fn . Делая это, мы создаем наш собственный пользовательский метод jQuery, который можно использовать в упакованном наборе элементов DOM.

По сути, плагин, прикрепленный к jQuery.fn позволяет нам создавать наши собственные пользовательские методы, аналогичные любым из найденных в API. Это потому, что когда мы присоединяем нашу функцию плагина к jQuery.fn , наша функция включается в цепочку прототипов — $.fn.count = function(){} — для объектов jQuery, созданных с использованием функции jQuery. Если это jQuery.fn воображение, просто помните, что добавление функции в jQuery.fn означает, что ключевое слово this внутри функции плагина будет ссылаться на сам объект jQuery.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
$.fn.count = function () {
      var $this = $(this);
      $this.text(‘0’);
      var myInterval = window.setInterval(function () {
          // Interval for counting
          var currentCount = parseFloat($this.text());
      }, 1000);
  };
  })(jQuery);
</body>
</html>

Примечания: добавляя плагин к объекту jQuery.fn , мы, по сути, говорим, что наш плагин хотел бы использовать функцию jQuery для выбора контекста (элементы DOM). Если вашему плагину не требуется определенный контекст (другими словами, набор элементов DOM), в котором он должен работать, вам может не понадобиться подключать этот плагин к $.fn . Возможно, имеет смысл добавить его как служебную функцию в пространство имен jQuery.


Когда вы присоединяете плагин к объекту jQuery.fn , ключевое слово, которое используется внутри присоединенной функции плагина, будет ссылаться на текущий объект jQuery.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
$.fn.count = function () {
      // «this» is equal to jQuery(‘#counter1’)
      alert(this);
      alert(this[0]);
      alert(this[0].id);
  };
  })(jQuery);
</body>
</html>

Крайне важно, чтобы вы точно указали ключевое слово в функции плагина.


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

Для этого мы используем функцию jQuery each() , которая является общим итератором как для объектов, так и для массивов, в основном упрощая циклы. В приведенном ниже примере кода мы используем функцию для перебора самого объекта jQuery. Внутри функции, которая передается each() , ключевое слово this будет ссылаться на элементы в наборе оболочки jQuery.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <div id=»counter2″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
       $.fn.count = function () {
           this.each(function () {
               // «this» is the current jQuery object
               var $this = $(this);
               $this.text(‘0’);
               var myInterval = window.setInterval(function () {
                   // Interval for counting
                   var currentCount = parseFloat($this.text());
               }, 1000);
           });
       };
   })(jQuery);
</body>
</html>

Использование функции each() крайне важно, если вы хотите, чтобы плагин использовал неявную итерацию.


Как правило, большинство плагинов возвращают сам объект jQuery, чтобы плагин не разрывал цепочку. Другими словами, если плагину не нужно специально возвращать значение, он должен продолжить цепочку, чтобы к набору оболочки могли быть применены дополнительные методы. В приведенном ниже коде мы возвращаем объект jQuery с return this; Заявление, чтобы цепочка не была нарушена. Обратите внимание, что я вызываю цепочку для методов parent() и append() после вызова плагина count() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <div id=»counter2″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
$.fn.count = function () {
       return this.each(function () {
           // Return the jQuery object, or «this» after each()
           var $this = $(this);
           $this.text(‘0’);
           var myInterval = window.setInterval(function () { var currentCount = parseFloat($this.text()); var newCount = currentCount + 1; $this.text(newCount + »); }, 1000);
       });
   };
   })(jQuery);
       .append(‘<p>Chaining still works!</p>’);
</body>
</html>

Примечания: Возможно сделать плагин деструктивным методом, просто не возвращая объект jQuery.


Плагины обычно содержат параметры по умолчанию, которые будут действовать как базовая конфигурация по умолчанию для логики плагинов. Эти параметры используются при запуске плагина. В приведенном ниже коде я defaultOptions объект defaultOptions содержащий одно свойство ( startCount) и значение ( 0 ). Этот объект хранится в функции count $.fn.count.defaultOptions . Мы делаем это так, что параметры настраиваются снаружи плагина.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <div id=»counter2″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
$.fn.count = function () {
       return this.each(function () {
           var $this = $(this);
           $this.text($.fn.count.defaultOptions.startCount + »);
           var myInterval = window.setInterval(function () { var currentCount = parseFloat($this.text()); var newCount = currentCount + 1; $this.text(newCount + »); }, 1000);
       });
   };
   })(jQuery);
</body>
</html>

Как правило, параметры плагина по умолчанию могут быть перезаписаны пользовательскими параметрами. В приведенном ниже коде я customOptions объект customOptions в качестве параметра функции плагина. Этот объект объединяется с объектом defaultOptions для создания единого объекта options . Мы используем служебный метод jQuery extension extend() для объединения нескольких объектов в один объект. Метод extend() предоставляет отличную утилиту для перезаписи объекта новыми свойствами. С этим кодом плагин теперь может быть настроен при вызове. В этом примере мы передаем плагину count произвольное число (500), которое будет использоваться в качестве начальной точки для подсчета. Этот пользовательский параметр переопределяет параметр по умолчанию (0).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <div id=»counter2″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
       $.fn.count = function (customOptions) {
           // Create new option, extend object with defaultOptoins and customOptions
           var options = $.extend({}, $.fn.count.defaultOptions, customOptions);
           return this.each(function () {
               var $this = $(this);
               // or to a custom option value if it is passed to the plugin
               $this.text(options.startCount + »);
               var myInterval = window.setInterval(function () { var currentCount = parseFloat($this.text()); var newCount = currentCount + 1; $this.text(newCount + »); }, 1000);
           });
       };
   })(jQuery);
        jQuery(‘#counter1, #counter2’).count({ startCount: 500 });
  
    </script>
</body>
</html>

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div id=»counter1″></div>
    <div id=»counter2″></div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
       $.fn.count = function (customOptions) {
           var options = $.extend({}, $.fn.count.defaultOptions, customOptions);
           return this.each(function () {
               var $this = $(this);
               var myInterval = window.setInterval(function () { var currentCount = parseFloat($this.text()); var newCount = currentCount + 1; $this.text(newCount + »); }, 1000);
           });
       };
   })(jQuery);
        jQuery.fn.count.defaultOptions.startCount = 200;
        jQuery(‘#counter2’).count({ startCount: 500 });
</body>
</html>

В зависимости от природы плагина может быть критически важно, чтобы плагин вызывался как обычно (через элементы и события DOM), так и программно. Рассмотрим диалоговый плагин. Будут времена, когда модал / диалог откроется на основе пользовательских событий. В других случаях диалог должен открываться на основе событий среды или системы. В этих ситуациях вы все равно можете вызвать свой плагин без каких-либо элементов в DOM, создав элемент на лету, чтобы вызвать плагин. В приведенном ниже коде я вызываю плагин dialog() при загрузке страницы, сначала создав элемент для вызова моего плагина.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang=»en»>
<body>
    <a href=»#» title=»Hi»>dialog, say hi</a> <a href=»#» title=»Bye»>dialog, say
    bye</a>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
       $.fn.dialog = function (options) { var text = this.attr(‘title’) ||
   })(jQuery);
        jQuery(‘a’).click(function () { // Invoked by user event
            $(this).dialog();
        });
        $(window).load(function () { // Create DOM element to invoke the plugin
            jQuery(«<a></a>»).attr(‘title’, ‘I say hi when invoked!’).dialog();
        });
</body>
</html>

Очевидно, что этот шаблон может сильно варьироваться в зависимости от параметров, сложности и функциональности плагина. Дело в том, что плагины могут вызываться через существующие элементы DOM, а также созданные на лету.


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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang=»en»>
<body>
    <div>Out And In Fade</div>
    <div>Out And In Fade</div>
    <script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js»></script>
    <script> (function ($) {
$.fn.outAndInFade = function (customOptions) {
       var options = $.extend({}, $.fn.outAndInFade.defaultOptions, customOptions || {});
       return this.each(function () {
           $(this).fadeOut().fadeIn(‘normal’, function () { // Callback for fadeIn()
               // Call complete() function, pass it «this»
               if ($.isFunction(options.complete)) {
                   options.complete.apply(this);
               }
           });
       });
   };
       $.fn.outAndInFade.defaultOptions = {
           complete: null // No default function
       };
   })(jQuery);
       // Change background-color of the element being animated on complete.
       // Note: «this» will refer to the DOM element in the wrapper set.
       complete: function () { $(this).css(‘background’, ‘#ff9’);
   });
</body>
</html>