Открыть меню    

Плагины jQuery: подробное руководство

Содержание

Введение

Эта статья поможет вам научиться разрабатывать свои собственные jQuery плагины (модули). Статья предполагает, что у читателя уже есть базовые знания Javascript. Важно, чтобы пользователь, прежде чем приступить к работе с jQuery, был знаком хотя бы с основными принципами работы Javascript.

Так важнейшим является понятие объекта. Уверен, что вы с ним знакомы, однако если это не так, я настоятельно рекомендую воспользоваться любым поисковиком и восполнить этот пробел. Объекты являются фундаментальными блоками объектно-ориентируемого программирования (OOП); ООП своим происхождением во многом обязано другим языкам программирования.

Чтобы по-настоящему понять, как создаются плагины jQuery, нужно знать, как работают объекты Javascript.

При изучении создания plugin'ов полезно одновременно самому ставить свои собственные эксперименты. Не нужно «копи-пастить» исходный код с чужих примеров. Вместо этого попытайтесь понять все, написав свой собственный код с нуля.

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

два способа создать плагин jQuery

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

Итак, чтобы разрабатывать плагины, надо как минимум знать, что же такое Javascript объект. Объектами, например, являются String (строка) , Date и Array (массив). Существуют и другие объекты.

Объекты Javascript

Возможно, вы уже освоили создание и вызов функций Javascript. Функции – это объекты в Javascript. Понять этот принцип чрезвычайно важно. Даже если вы знакомы с объектами таких языков, как C++, принцип работы объектов Javascript немного иной.

Так как функции являются объектами, к ним можно создать идентификаторы. Имя у идентификаторов может быть любое, каким мы хотим назвать свой объект. Позже мы можем расширить это объект. Давайте взглянем, как можно создать свой объект:

       
var myObject = function(param1, param2)
{
    /* сделать что-нибудь */
};

Только что вы создали свой собственный объект с именем myObject. Обратите внимание на точку с запятой в конце этого описания.

В ядре любой библиотеки Javascript расположен основной объект. Этот объект создается таким же образом, каким мы только что создали myObject.

Основной объект библиотеки jQuery

Давайте теперь взглянем на описание основного объекта jQuery.

       
var jQuery = window.jQuery = window.$ = function(selector, context)
{
    /* сделать что-нибудь */
};

Конечно же, часть /* сделать что-нибудь */ содержит в себе описания всей библиотеки jQuery, заключающей в себе такие функции, как css(), click() и animate(). В следующих статьях я расскажу о них подробно.

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

Заметьте, что в приведенном выше описании jQuery = window.jQuery = window.$. Это означает, что создан один объект, а получить к нему доступ можно с помощью любого из трех имен переменной. Когда мы используем основной объект библиотеки посредством его имени jQuery(), это все равно, что использовать $(), window.$() или window.jQuery(). Помните, что в Javascript ключевое слово «window» - это заранее созданный объект; поэтому код Javascript, не являющийся частью какой-либо функции, работает в контексте исполнения, в котором для определения переменных используется глобальный объект. Каждый раз, когда вы создаете переменную, например, x = 1, она автоматически становится доступной посредством своего эквивалента window.x.

Также и со знаком доллара, который является именем переменной. Если бы библиотека jQuery была присвоена переменной с именем x, команды jQuery мы бы вызывали с помощью х, то есть так: x('#div').hide(). Но так как эта переменная была приписана знаку доллара (который является допустимым именем для переменной в Javascript), то мы используем следующую конструкцию: $('#div').hide();

Попытайтесь воспроизвести это сами в пустом файле Javscript. Присвойте var $ = 1 и выведите ее с помощью окна предупреждения наподобие alert($). Вы увидите, что знак доллара есть ни что иное, как имя переменной, подобно многим другим. И ничего особенного в нем нет. Его даже можно использовать в сочетании с другими символами: к примеру, var Dollar$ = 10. Да, когда имя переменной состоит из одного только знака доллара ($), выглядит это странно, однако между ним и любыми другими переменными нет в сущности никакой разницы.

Так почему разработчики jQuery решили использовать знак доллара? Ну, иногда возникает необходимость использовать jQuery с другими библиотеками. Используя уникальное имя для библиотеки, разработчики избегают конфликтов с другими библиотеками или функциями, которые вы, возможно, захотите использовать вместе с jQuery. В общем, если вы планируете использовать другие, не написанные вами, библиотеки, знак доллара ($) предотвратит конфликты. Если бы каждый называл свои Javascript библиотеки "my_library", то имена переменных неизбежно бы конфликтовали друг с другом, делая невозможным их общее использование. Знак доллара не дает этому случиться. Вышесказанное означает также и то, что вам не стоит создавать свои собственные переменные и давать им имя в виде знака доллара.

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

javascript

    var func1   = function() { alert("hello from func1"); }
    func1.func2 = function() { alert("hello from func1.func2"); };
    var _       = function() { alert("hello from _"); }
    var \\u0024  = function() { alert("hello from $ defined as \u0024"); }
    var Ø       = function() { alert("hello from Ø"); }
    var $$$$$   = function() { alert("hello from $$$$$"); }

    func1();
    func1.func2();
    _();
    $();
    Ø();
    $$$$$();   

Возвратимся к примеру создания объекта jQuery.

var jQuery = window.jQuery = window.$ = function(selector, context)

Обратите внимания, что параметры selector и context переданы только что созданному объекту jQuery. Параметр selector - это CSS селектор. Мы передаем строку текста, которая просит jQuery отобрать элемент. Когда это произойдет, эта функция возвратит идентификатор отобранного элемента или его положению в памяти компьютера. Другими словами: Функция jQuery() возвращает объект jQuery.

Давайте рассмотрим на практике, что позволяет нам делать объект jQuery:

JQuery

       jQuery("div").hide();

Приведенная выше функция найдет все расположенные на странице div элементы и спрячет их. jQuery функция hide() - это что-то вроде мини pluginа. Он прячет элементы путем использования CSS объявления display:none. С этим объявлением, я уверен, вы уже сталкивались и использовали в своем собственном CSS коде.

Вы можете расширить функциональности jQuery, добавив свою собственную функцию, которая будет прятать элементы согласно вашим указаниям. К примеру, вы могли бы добавить функцию с именем hideitmyway(); она будет прятать элемент посредством объявления visibility: hidden вместо display:none. В этом и заключается суть разработки плагинов jQuery: вы расширяете его функциональность путем добавления своих собственных функций.

Плагины могут и не должны ограничиваться одной функцией. Вы можете создать плагин в виде галереи изображений, который будет превращать div элементы в прокручиваемые блоки, содержащие изображения; блок и изображения передадим плагину в качестве параметров. Например:

var ImageGallery = function(div_container, images_1_2_3) { ... };

Вы можете инициализировать плагин, написав следующий код:

ImageGallery("#container", "myimage.jpg, anotherone.png, mycat.gif");  

Итак, этим мы вызовем функцию, которую вы присвоили объекту, что дальше?

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

Где на самом деле начинает исполняться код плагина?

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

Помните, как несколькими параграфами выше я писал, что window.x это тоже самое, что и var x? В Javascript таким же способом определяются не только переменные, но и объекты. И несколько объектов уже существуют. Например, уже знакомый вам атрибут html onload тега body.

<body onload = "alert('Hello!')">...

Это не единственный способ добавить код, реагирующий на событие загрузки страницы. С Javascript это можно сделать следующим образом.


// Переопределяем событие onload тега body 
window.onload = function()
{
    /* Когда страница загружена, сделать что-нибудь ... */
}

Помните ту часть вашей страницы, на которой говорится body onload = "..."? Присовив window.onload новую функцию (подобно тому, как показано на примере выше), это тоже самое, что и помещение кода Javascript в body onload = "...here...". Надо только быть уверенным, что вы вызываете window.onload из тега script , где-то в теге head вашей страницы. Многие не знают, что слово "onload" в теге body официально считается атрибутом тега body. Если у вас есть желание заняться разработкой jQuery серьезно, вам необходимо знать существующие атрибуты тегов. Например потому, что jQuery имеет функцию attr(), которая возвращает значение указанного атрибута. Важно знать, что означает тот или иной атрибут и ссылаться к ним по их именам.

Важно: Если в HTML вы имеете Javascript код в пределах атрибута тега body onload, этот код будет переписывать функцию window.onload! И код window.onload не будет исполняться. Поэтому, чтобы избежать этого конфликта, старайтесь не использовать windown.onload вместе с атрибутом onload. Обычно разработчики стараются избежать использования атрибута onload всеми доступными способами, однако есть такие случаи, где добиться этого не получается. Общее же правило – если можете, не используйте его. Переопределите javascript.load своей собственной функцией.

Что было раньше: яйцо или курица?

В смысле атрибут HTML тега body onload или window.onload? Который из них будет исполняться первым? Вы можете добавить свою собственную функцию window.onload, но, как я писал ранее, код в вашем атрибуте onload перепишет ее.

Что ж, знаете что, по существу ни яйцо, ни курица нельзя назвать первенцем. В нашем примере для того, чтобы инициализировать плагины jQuery, мы используем совершенно иной тип яйца. Я имею ввиду функцию $(document).ready(). Она исполняется и перед кодом body onload и перед window.onload. Так что же такое $(document).ready()? Это место, где мы инициализируем наш плагин. Функция ready() описана ниже среди остальных функций, которые мы обсуждали ранее, скажу лишь, что ready() добавляет функцию, выполняющуюся всякий раз, когда объектная модель документа (DOM) готова к использованию.. Давайте посмотрим на порядок, в котором все будет исполняться.

HTML


<html>
<head>
<script type = "text/javascript" src = "https:...jquery.min.js"></script>
<script type="text/javascript">

window.onload = function() {
  alert("window");    
         // Не будет исполняться (перезаписана атрибутом onload ниже!)
};

$(document).ready(function() {
   alert("document ready");    
        // выполняется первым
});
  
</script>
</head>
<body onload = "alert('Я просто перезаписываю window.onload')"> 
       <!-- выполняется вторым //-->

Мотивом построения такой структуры послужило мое желание показать вам последовательность исполнения кода, при понимании которой у разработчиков зачастую возникают определенные проблемы. Если вы из примера выше удалите атрибут onload тега body, функция window.onload начнет исполняться снова, потому что она не будет перезаписана (или замещена как в случае с объектами).

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

Зачем разработчики jQuery создали Document Ready (готовность документа)?

Прежде всего функциональность "Document Ready" уже существует в некоторых браузерах. Проблема же заключается в том, что для того чтобы использовать ее, вам нужно написать код, который для каждого браузера выглядит по-своему. Если только вы не используете jQuery.

Зачем Document Ready нужна? Может просто воспользоваться популярным событием onload посредством атрибута тега body, или использовать функцию window.onload? Можно, но не нежелательно.

Чтобы понять это, вам нужно знать, что такое DOM. DOM – это объектная модель документа (Document Object Model). Уверен, что вы знакомы с таким понятием, как ветвление HTML тегов, которое означает, что некоторое теги можно определять внутри других тегов и т. д.

DOM – это модель, которая следит за всеми элементами и позволяет нам увидеть их в виде дерева данных. Раньше эта модель использовалась главным образом для внутренних процессов, теперь же, в связи с развитием jQuery и динамичных веб-приложений, например, развитие графических интерфейсов пользователя (известные как GUI или просто UI), востребованность в понимании дерева DOM существенно увеличилась.

Уважай DOM

В качестве примера DOM рассмотрим DIV A, B и C. Если DIV B находится внутри DIV A, это означает, что он является «ответвлением» DIV A, который в свою очередь является «родителем». Если же и DIV C является ответвлением DIV A, тогда DIV B и DIV C – это дочерние элементы по отношению к DIV A и соседи между собой.

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

Вот базовая структура DOM, использующая HTML элементы.

дерево DOM

Как вы поняли, DOM дерево-подобная структура, содержащая данные всего HTML документа.

DOM загружается прежде, чем все остальное, даже перед тем как страница отобразится в вашем браузере. То есть данные DOM уже существуют в то время как страница только подгружается. Почему бы не воспользоваться этим преимуществом и не начать инициализировать плагин в это время? Зачем ждать onload или пока загрузится визуальная часть GUI, в конце концов, событие onload будет ждать загрузки изображений, что может занять массу времени. Чтобы инициализировать плагин, ждать совсем необязательно.

Так зачем все-таки разработчики jQuery создали функцию $(document).ready(...)? Потому что с ее помощью возможно кроссбраузерное исполнения кода сразу по окончания загрузки дерева DOM и перед тем как содержимое страницы будет показано. Помните… что разным браузерам необходим свой Javascript код для проверки загрузки DOM. А с jQuery достаточно одной удобной функции. Вот здесь мы и инициализируем свой плагин. Функция $(document)ready() используется не только для инициализации плагинов. Используйте ее для инициализации всех ваших переменных Javascript или объектов, даже если вы и не разрабатываете плагин.

Как создаеть plugin, как его инициализировать и запустить?

Самый простой способ создать свой собственный плагин, это следовать заранее определенной схеме, например той, которая расположена ниже.
Также вам в помощь статьи:
Создание плагина jquery,
Основы jquery.

Давайте представим, что мы создаем плагин для слайд-шоу. Я не стану вдаваться в детали создания полноценного слайд-шоу плагина. Данный пример объясняет только один способ создания плагина с нуля, его инициализации и запуска (выполнения).

Расположенный ниже код пойдет в отдельный файл типа "slideshow.js" и будет подключен к вашей странице HTML внутри тегов head и script. Приведенный код можете рассматривать как стартовую точку при разработке своих плагинов.

                 
// Плагин, параметры по умолччанию 
//(можем переопределить в процессе инициализации плагина)
// Здесь также определяется порядок, в котором параметры должны буть переданы
// в ф-ю инициализации
// при инициализации недостающие аргументы берутся из  ф-и options 
function options()
{
    this.params = {
    data : Array ("monalisa.jpg",     // [0] путь к изображению
                  "#container"        // [1] блок плагина
                 ) };
};
// Определяем основной объект плагина, он пустой и это хорошо
$.Slideshow = function()
{
}
// Инициализируем плагин (опущенные аргументы определяются принудительно)
$.Slideshow.initialize = function()
{
  
  // Здесь я делаю интересную вещь, которая требует объяснения  
  // Я, как правило, использую options.params.data в двух ф-ях      
  // plugin.initialize и plugin.run                                                     
  // Отметьте, что для этой ф-и мы не определили аргументы  
  // В данном случае это необязательно                                                  
  // Так как получить к ним доступ можно при помощу массива arguments
  // Общее число аргументов, соот-но равно  arguments.length     
      
    $.options = new options();

    for(var i = 0; i < arguments.length; i++)
        $.options.params.data[ i ] = arguments[ i ];
}
// // Управление плагином
$.Slideshow.run = function()
{
    // Здесь пишем код, который осуществляет работу плагина плагина                                    
    // Используем параметры, хранящиеся в объекте  "params"                                                                                                   
    // Давайте вставим изображение, которое было передано, как параметр плагина,                                         
    // в DIV, который также может быть передан плагину в качестве параметра
    // Отметьте, что параметры переданные  ф-и инициализации доступны через:                          
    // $.options.params.data[ X ], где X индекс параметра, к которому вам необходим доступ             
    //  индексы определяются порядком следования параметров при передачи  их в ф-ю инициализации      


$($.options.params.data[ 1 ]).html('<img src = "' + $.options.params.data[ 0 ] + '"/>');

     // Конечно, эта та часть, которую вы можете преобразовать как вам необходимо      
};        

Можно ли помещать параметры в сам объект Slideshow? Да, я же решил поместить их в отдельный объект options и сделать их доступными на глобальном уровне. Помимо этого способа существуют и другие способы создания плагина и хранения его параметров по умолчанию. По мере изучения Javascript, объектов и переменных вы освоите и их. Мне же хотелось преподнести все в виде простых блоков.

Что же происходит на приведенном выше примере? Говоря $.Slideshow = function() { ... }, вы прикрепляете новую функцию к объекту библиотеки jQuery ($), тем самым расширяя его функциональность. Назовем новый плагин Slideshow. Присоединив новую функцию, можно начинать использовать ее через $.Slideshow(); Конечно же к этой функции можно добавить параметры, это просто пример.

Если вы готовы протестировать свой плагин, запустите $.Slideshow.initialize() из функции "готовность документа‛, а затем вызовите метод функцию run(), как показано ниже:

 
$(document).ready(function() {

    $.Slideshow.initialize("image.jpg", "#plugin_container");

    $.Slideshow.run();

});

Заметьте, что вы можете передать функции столько аргументов, сколько захотите. В функции initialize они описаны не подробно. Зато функция initialize автоматически их нумерует. Помните, что каждая функция является объектом? И функции это такие объекты, при создании которых к ним присоединяется массив аргументов. Нам даже не надо описывать эти аргументы в описании функции. Если же по какой-то причине вам надо быть точным, ради бога, используйте четкие описания аргументов.

Где-то на странице находится div элемент #plugin_container, и вы хотите, чтобы плагин использовал его в качестве основного контейнера. Вот здесь-то и происходит самое главное. Он просто селектор и вы можете выбирать любой элемент, какой захотите. Именно здесь визуальные данные (если таковые имеются) вашего плагина будут отображены. К примеру, можете взять первый параметр "image.jpg" и отобразить его в данном контейнере посредством следующей команды:

 
$.Slideshow.run = function()
{
    $($.options.params.data[ 1 ]).html('<img src = "' + $.options.params.data[ 0 ] + '"/>');
}

Помните, что $.options.params.data[ 0 ] содержит путь к изображению "image.jpg", а $.options.params.data[ 1 ] содержит идентификатор контейнера (div) плагина.

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

Комментарии к статье

аватарка пользователя
2014-06-01
Ильдар

Очень полезная статья) Хоть что-то начал понимать