Статьи

Плагины jQuery

Эта статья является отрывком из книги Эрл Кастледин и Крейга Шарки «От новичка до ниндзя» . Смотрите более подробную информацию ниже.

«Эй, теперь, когда все на месте — вы можете просто вернуться и поместить это меню из третьей фазы в раздел администратора? И можете ли вы добавить классные списки, которые вы сделали на последнем этапе, в эти списки в интерфейсе — и добавить эффект прокрутки, который вы сделали … вы можете просто скопировать и вставить код, верно? »

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

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

Создание плагина

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

Настройка

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

Все, что нам нужно сделать, чтобы плагин вызывался как обычные действия jQuery — это прикрепить функцию к прототипу jQuery. В JavaScript свойство prototype любого объекта или встроенного типа данных может использоваться для расширения его новыми методами или свойствами. Для нашего плагина мы будем использовать свойство prototype самого базового объекта jQuery

Самый безопасный (только!) Способ сделать это — создать частную область видимости для функции jQuery Этот трюк JavaScript гарантирует, что ваш плагин будет хорошо работать, даже на страницах, где человек использует функцию $ для не-jQuery целей:

 (function($) {
  // Shell for your plugin code
})(jQuery);

Этот код может находиться в любом месте вашего скрипта, но стандартная практика заключается в том, чтобы поместить его в отдельный файл JavaScript с именем jquery.pluginname.js Теперь, когда у вас есть отдельный файл, вы можете легко использовать его в будущих проектах или поделиться им со всем миром!

Внутри этой защитной оболочки мы можем безнаказанно использовать псевдоним $. Это все, что есть на пути к предварительным экзаменам, так что пришло время начать писать плагин. Сначала нам нужно дать ему имя highlightOnce и прикрепить его к плагину jQuery, $.fn

  (function($) {
  // Shell for your plugin code
  $.fn.highlightOnce = function() {
    // Plugin code
  }
})(jQuery);

Внутренне $.fn Именно здесь jQuery размещает свои действия, поэтому теперь, когда мы добавили наше настраиваемое действие, мы можем назвать его так, как если бы оно было встроено в jQuery.

На данный момент наш код выглядит как плагин jQuery, но он не будет действовать как один — осталось сделать еще одну задачу. Если бы мы выполнили некоторые операции внутри нашего кода плагина сейчас, мы бы фактически работали над всем выделением сразу ; например, если мы запустим $('p').highlightOnce() Нам нужно поработать с каждым элементом по одному и вернуть элемент, чтобы цепочка jQuery могла продолжаться. Вот довольно стандартная конструкция для плагинов:

 // Plugin code
return this.each(function() {
  // Do something to each item
});

Теперь у вас есть хороший скелет для создания простых плагинов. Сохраните этот план, чтобы быстро создавать новые плагины!

Добавление функциональности плагина

Наш плагин highlightOnce готов к работе, поэтому давайте поработаем. Вся структура, которую мы добавили до сих пор, — это просто строительные леса — теперь пришло время создать здание! Тип кода, который мы можем запустить в духе нашего плагина, точно такой же, как код, который мы привыкли писать; мы можем получить доступ к текущему объекту с помощью конструкции $(this)

Первая функция, которую должен выполнить наш плагин, — выделить каждый выбранный элемент, поэтому мы просто установим фон в ярко-желтый цвет. Далее нам нужно обработать, когда пользователь наведет курсор на элемент, чтобы мы могли убрать выделение. Мы хотим, чтобы это происходило только один раз, как только элемент будет возвращен к исходному цвету (не забывайте, что для этого нам нужен компонент эффектов пользовательского интерфейса jQuery):

 // Do something to each item
$(this)
  .data('original-color', $(this).css('background-color'))
  .css('background-color', '#fff47f')
  .one('mouseenter', function() {
    $(this).animate({
      'background-color': $(this).data('original-color')
    }, 'fast');
  });

Просто случается, что действие jQuery точно соответствует нашим потребностям: одно действие. Функционально onebind Различие между ними состоит в том, что событие будет запускаться только один раз , после чего событие автоматически отменяет привязку.

Для нашего кода мы сохраняем текущий цвет фона в хранилище datamouseover Когда пользователь наводит курсор на элемент, запускается наш код и цвет фона возвращается к исходному. И с этим наш плагин готов к использованию:

 $('p')
  .hide()
  .highlightOnce()
  .slideDown();

Это довольно захватывающе: наша функциональность заключена в подключаемый модуль многоразового использования, который мы разместили между действиями hideslideDown Видя, что 11 строк кода — это все, что требовалось (и шесть из них — стандартные плагины для плагинов!), Вы можете увидеть, что стоит превратить любую функциональность, которую вы собираетесь повторно использовать, в плагин!

Добавление параметров

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

Мы знакомы с тем, как работают опции с точки зрения пользователя плагина, так как мы передали опции практически каждому плагину, который мы использовали в книге. Опции позволяют нам изменять функциональность плагина как тонким, так и более очевидным образом, чтобы его можно было использовать в самых разных ситуациях.

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

 $.fn.highlightOnce = function(color) {
  ⋮
  $(this).css('background-color', color  || '#fff47f')
  ⋮
};

Плагин может быть вызван цветом, но также может быть вызван без параметров — в этом случае будет использоваться значение по умолчанию (благодаря оператору JavaScript ||). Давайте выделим наши параграфы зеленым цветом:

 $('p')
  .hide()
  .highlightOnce('green')
  .slideDown();

Если у вас есть один или два простых варианта, которые всегда требуются, этот подход подойдет. Но когда ваши плагины станут более сложными, вы получите множество настроек, и ваши пользователи захотят переопределить некоторые из них и оставить значения по умолчанию для других. Здесь мы обратимся к более сложной буквенной записи объекта.

Это не страшно — вы уже знаете, как определить этот тип объекта настроек. Мы использовали их для animatecss Преимущество объекта «ключ / значение» заключается в необходимости определения только одного параметра, в котором пользователи смогут указывать несколько параметров. Наш первый шаг — установить значения по умолчанию для каждой опции:

 $.fn.highlightOnce.defaults = {
  color : '#fff47f',
  duration : 'fast'
}; 

Теперь у нас есть значения по умолчанию в качестве объекта, поэтому нам нужно использовать функцию jQuery $.extend Эта удобная функция имеет несколько применений, но для наших целей мы будем использовать ее для расширения объекта путем добавления всех свойств из другого объекта. Таким образом, мы можем расширить параметры, которые пользователь передает, с нашими настройками по умолчанию: плагин будет иметь значения, указанные для каждой опции уже, и если пользователь указывает одну из них, значение по умолчанию будет переопределено. Отлично! Давайте посмотрим на код:

 $.fn.highlightOnce = function(options) {
  options = $.extend($.fn.highlightOnce.defaults, options);

  return this.each( … );
};

Наша переменная options Теперь мы можем использовать настройки в нашем коде:

 $(this)
  .data('original-color', $(this).css('background-color'))
  .css('background-color', options.color)
  .one('mouseenter', function() {
    $(this).animate({
      'background-color': $(this).data('original-color')
    }, options.duration);
  });

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

 $('p')
  .hide()
  .highlightOnce({duration: 2000})
  .slideDown();

Добавление обратных вызовов

Вы видели, как функции и события обратного вызова могут быть очень полезными. Многие эффекты и элементы управления в книге основаны на них, и многие из используемых нами плагинов дали нам доступ к обратным вызовам для настройки их функциональности. Обратные вызовы — это механизм, предоставляющий пользователям вашего плагина возможность запускать собственный код, основанный на событиях, происходящих внутри вашего плагина. Как правило, у вас будет довольно хорошее представление о том, какие события вы хотели бы представить своим пользователям. Например, для нашего плагина highlightOnce мы могли бы захотеть запустить дополнительный код, когда эффект настроен, когда эффект заканчивается, и, возможно, когда затухание начинается.

Чтобы продемонстрировать, давайте попробуем выставить событие setupmouseovercompleteanimate$.fn.highlightOnce.defaults = {
color : '#fff47f',
duration : 'fast',
setup : null,
complete: null
};

 $(this)
  .data('original-color', $(this).css('background-color'))
  .css('background-color', options.color)
  .one('mouseenter', function() {
    $(this).animate(
      {'background-color': $(this).data('original-color')},
      options.duration,
      options.complete
    );
  });

  // Fire the setUp callback
  $.isFunction(options.setup) && options.setup.call(this);

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

 complete 

Выше мы можем видеть оба типа обратных вызовов. animate animate setup Однако, с обработчиком $.isFunction Мы обращаемся к jQuery и немного продвинутого JavaScript для выполнения кода. Сначала мы проверяем, является ли обратный вызов функцией с удобным действием true false null Если это последнее (что, скорее всего, потому, что пользователь оставил значения по умолчанию такими, какими они были, и в этом случае оно все равно будет $.isFunction

Дополнительные служебные функции

В дополнение к $.isArray$.isPlainObject$.isEmptyObjectoptions.setup() Эти функции предоставляют вам несколько способов выяснить природу и свойства конструкции JavaScript.

Если обратный вызов был определен, нам нужно запустить его. Есть несколько способов запустить функцию JavaScript, и самый простой — просто вызвать ее: default Это будет работать нормально, но проблема в том, что он вызывается в области действия объекта по call Таким образом, функция обратного вызова не сможет определить, с каким элементом DOM она имеет дело. Чтобы исправить это, мы используем call Первый параметр, который вы передаете для thisthis В нашем примере мы передаем $(this)

С исправленной областью мы можем теперь использовать complete

 $('p')
  .hide()
  .highlightOnce({
    color: '#FFA86F',
    complete: function() {
      $(this).slideUp();
    }
  })
  .slideDown();

Обратный звонок в стиле jQuery

Вы могли заметить, что обратные вызовы jQuery лучше интегрированы, чем названные события нашего плагина. Например, в действии hide Нет необходимости включать пару ключ / значение, как мы делали выше. В чем секрет? Оказывается, что-то вроде хака на JavaScript. Если вы обнаружите, что первым параметром является функция, а не объект, вы можете предположить, что был задан только обратный вызов, поэтому вы перенесете параметры в сторону.

Вот (усеченный) пример из базовой библиотеки jQuery, часть действия load Параметр params

 load: function( url, params, callback ){
  // If the second parameter is a function
  if ( jQuery.isFunction( params ) ){
    // We assume that it's the callback
    callback = params;
    params = null;

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

Давайте изменим наш плагин highlightOnce

 $.fn.highlightOnce = function(options, callback) {
  if ($.isFunction(options)) {
    callback = options;
    options = null;
  }
  options = $.extend($.fn.highlightOnce.defaults,options);

  return this.each(function() {
    // Do something to each item
    $(this)
      .data('original-color', $(this).css('background-color'))
      .css('background-color', options.color)
      .one('mouseenter', function() {
        $(this).css('background-color', '');
        $.isFunction(callback) && callback();
      });
  });
};
примечание: хотите больше?

Проверьте книгу и купите ее онлайн на Вы также можете скачать архив кода книги, проверить наличие обновлений и ошибок или проконсультироваться с процветающим сообществом разработчиков JavaScript и jQuery на форумах SitePoint .