Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Свой плагин: $.fn

Плагин jQuery — это новый метод, который становится доступен у любого набора элементов, как addClass() или fadeOut(). Методы наборов хранятся в объекте $.fn, поэтому плагин — это просто функция, добавленная в $.fn. Так устроены тысячи готовых плагинов: слайдеры, маски ввода, всплывающие окна.

Где лежит плагин

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

todo/
├── index.html
├── jquery.counter.js
└── script.js
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="jquery.counter.js"></script>
<script src="script.js"></script>

По традиции имя файла начинается с jquery..

Первый плагин

Плагин taskCounter пишет рядом со списком, сколько в нём задач:

<ul id="tasks">
  <li>Купить хлеб</li>
  <li>Позвонить Олегу</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $.fn.taskCounter = function () {
    return this.each(function () {
      const count = $(this).children('li').length;
      $(this).after($('<p>').text('Задач: ' + count));
    });
  };
 
  $('#tasks').taskCounter();
</script>

Под списком появилась строка «Задач: 2». Внутри плагина this — сам набор jQuery, поэтому его не нужно оборачивать в $. Метод each() обрабатывает каждый элемент набора по отдельности, а return возвращает набор, чтобы после плагина можно было продолжить цепочку.

Настройки

Плагин принимает объект настроек и дополняет его значениями по умолчанию через $.extend() из прошлого урока:

<style>
  .highlight { background: gold; }
</style>
 
<ul id="tasks">
  <li>Купить хлеб</li>
  <li>Срочно: позвонить Олегу</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $.fn.highlightTasks = function (options) {
    const settings = $.extend({ word: 'Срочно', className: 'highlight' }, options);
 
    return this.find('li').each(function () {
      $(this).toggleClass(settings.className, $(this).text().includes(settings.word));
    }).end();
  };
 
  $('#tasks').highlightTasks().css('padding', '8px');
</script>

Пункт со словом «Срочно» подсвечен жёлтым. Вызов highlightTasks({ word: 'хлеб' }) подсветил бы другой пункт. Метод end() возвращает набор, который был до find(), поэтому css() применяется к самому списку.

Защита $

В файле плагина код оборачивают в функцию, которая получает jQuery под именем $:

// jquery.counter.js
(function ($) {
  $.fn.taskCounter = function () {
    return this.each(function () {
      const count = $(this).children('li').length;
      $(this).after($('<p>').text('Задач: ' + count));
    });
  };
})(jQuery);

Так плагин работает, даже если на странице $ занят другой библиотекой или jQuery подключена в режиме noConflict, как в WordPress.

Частая ошибка

Не вернуть this из плагина. Тогда вызов вернёт undefined, и цепочка $('#tasks').taskCounter().addClass('ready') упадёт с ошибкой Cannot read properties of undefined. Всегда заканчивайте плагин return this или return this.each(...).

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.