Основы создания плагинов для jQuery (1.x и 2.x)

Приветствую всех посетителей моего блога! 🙂

Сегодня я хочу рассказать об основах создания плагинов к jQuery, популярной JavaScript’овой библиотеки.

Несмотря на то, что в последнее время все чаще на сайтах используют такие популярные JavaScript фреймворки, как например Angular, Backbone, Knockout и другие, jQuery по-прежнему является востребованным.

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

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

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

На практике для этого можно было бы использовать готовый плагин jQuery под названием timeago:

$(«.timago»).timeago();

В данном случае вызов timeago(), который идет после селектора, по сути и означает проинициализировать логику этого текста с датой, чтобы она изменялась на относительный текст «3 минуты назад», «час назад» и так далее …

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

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

Серверная часть выходит за рамки этого урока, но если кому интересно — у меня она реализована на Laravel 4й версии. И состоит всего из двух маршрутов: корневой маршрут отображает саму заглавную страницу с цитатами, а по урлу /quote  вызывается API, который возвращает нам в JSON-формате случайный текст, который и надо с некоторыми интервалами подставлять на главной странице.

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

Итак, пускай у нас имеется такая страница:

Здесь все просто:

  • в 4й строке мы подключаем сам jQuery
  • строки 8-12 содержат будут содержать инициализацию JavaScript-кода страницы
  • В элемент  #random-quote в строках 16-18 нам и нужно будет подгружать случайную цитату с сервера

Кто-то может сказать, что писать плагин для такой простой задачи — это как из пушки по воробьям: объем кода для этого весьма невелик и его вполне можно было бы поместить прямо на этой же странице, ну либо вынести в отдельный файл. Но это только на первый взгляд. Давайте представим, что будет, если нам потребуется иметь несколько таких элементов на этой странице? При таком подходе придется либо дублировать код, либо менять структуру страницы — присваивать всем этим элементам новый класс. Ну допустим. Но что мы будем делать, если нам потребуется, чтобы каждый такой элемент был уникален: в одном цитата обновлялась раз в 5 секунд, в другом раз в минуту. Или еще какие-то кастомизации? В этом случае наша задача усложняется.

Согласитесь, более элегантным решением было бы вешать на каждый такой элемент плагин jQuery вида:

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

Одним словом, «повесить» на элемент  .randomQuote({...}); означает проинициализировать всю логику его, связанную с обновлением цитат. Также, имея такой плагин, мы можем реализовать некоторый API: например, получить текущую цитату можно будет посредством

Или например сможем принудительно обновить цитату, вызвав

Но обо всем этом, а точнее о том, как это реализовать, расскажу теперь подробнее.

Итак, начнем с создания нового файла, который будет содержать наш плагин, и подключим его. В сообществе jQuery принято именовать файлы, содержащие расширения, в виде  jquery.<vendor>.<name>.js , либо в упрощенном виде, опустив <vendor> . Под  <vendor> подразумевается разработчик плагина, а под <name> — непосредственно имя плагина. В нашем случае мы можем ограничиться упрощенным видом и назвать файл  jquery.randomQuote.js . В зависимости от организации ресурсов вашего сайта, его нужно поместить в какой-то каталог. В моем случае это каталог js , чтобы я мог обратиться к нему по урлу /js/jquery.randomQuote.js .

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

Настало время рассказать именно об основах создания плагинов к jQuery.

Насколько вы знаете (я надеюсь), сам jQuery представляет из себя объект, доступный глобально как  jQuery  или, что применяется чаще, как просто $ . Далее по тексту я буду обращаться к нему именно через знак доллара для удобства и просто потому, что это наиболее распространенный вариант, но вскоре я остановлюсь на этом именовании подробнее.

Итак, все плагины jQuery содержатся в свойстве  $.fn . Каждый элемент этого свойства — это функция, которая вызывается при вызове соответствующего плагина. То есть в нашем случае, чтобы использовать плагин $("...").randomQuote();  нужно объявить и присвоить функцию в $.fn.randomQuote :

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

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

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

Итак, имея такую заглушку для плагина, нужно знать еще кое-что. Внутри этой функции-плагина, посредством this  мы можем обратиться к элементу, на который этот плагин был повешен. То есть в нашем случае, при $("#random-quote").randomQuote();  внутри плагина через this  мы как раз получим доступ к этому самому элементу $("#random-quote") . Также в конце кода функции-плагина нам желательно вернуть этот this , чтобы пользователь мог продолжить вызывать jQuery-методы над этим элементом по цепочке.

Теперь можно приступать к непосредственно написанию плагина.

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

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

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

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

Для проверки работы этих фкункций, можно вызвать update  при инициализации плагина, и повесить уже наконец этот плагин на элемент #random-quote .

 

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

Идем дальше, как и полагается — по пути усложнения функционала. Давайте теперь реализуем автообновление цитат, но не по фиксированному, а заданному в свойствах интервалу времени.

Первым делом нам нужно предусмотреть передачу объекта-контейнера свойств при инициализации плагина, чтобы можно было повесить плагин, указав настройки, например как я показывал в начале статьи:

Для этого добавим параметр options  в функцию-плагин и еще кое-что:

Теперь все переданные настройки будут хранится в локальной переменной settings , видимой отовсюду внутри плагина. Обратите внимание на две вещи:

  1. Используется jQuery-функция extend , которая объединяет два объекта в один. В нашем случае она объединяет объект с настройками по умолчанию с переданным пользователем настройками.
  2. Конструкция  options || {} обрабатывает случай, когда пользователь вообще не передал никаких настроек. Она означает буквально «взять объект options , или пустой объект, если options  не передан».

Теперь осталось написать инициализацию плагина, чтобы он обновлялся автоматически:

И вызывать эту функцию при инициализации плагина.

Итак, как передавать настройки в плагин мы разобрались. Давайте теперь рассмотрим, как можно реализовать простенький API нашего плагина на примере метода update .

Для этого нам потребуется немного изменить инициализацию плагина, а именно сделать проверку на тип первого аргумента, переданного пользователем. Если это строка — значит нужно выполнить какую-то API-логику. Если же это объект — то сделать то, что мы делали раньше. В этом нам поможет jQuery-функция isPlainObject . Вот как изменится инициализация:

Как видим, конструкция switch  обрабатывает все возможные варианты вызовов API нашего плагина. Теперь мы в любой момент времени, например по нажатию на кнопку на странице, можем «вручную» обновить цитату в элементе, просто вызвав:
Что еще может нам быть полезно уметь при написании плагинов? Выбрасывать различные события, связанные с плагином. Например, наш плагин должен выбрасывать событие каждый раз, когда меняется цитата. В этом случае пользователь сможет обрабатывать это, повесив следующую инструкцию:
Делается это очень просто: нам достаточно подправить метод setQuote  внутри плагина:
На этом все 🙂 Напоследок приведу полный код получившегося у меня плагина:

Поделиться в соц. сетях

3 thoughts on “Основы создания плагинов для jQuery (1.x и 2.x)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.