Первый плагин
Комом...
Для начала давайте вспомним, для чего нам нужны плагины? Мой ответ — для создания повторно используемого кода, причём с удобным интерфейсом. Давайте напишем такой код, начнём с простой задачки:
— По клику на параграф текст должен измениться на красный
JavaScript и даже не jQuery
Дабы не забывать истоки, начнём с реализации на нативном JavaScript:
// завернём всё в функцию
let loader = function () {
// находим все параграфы
let paragraphs = document.getElementsByTagName('P');
// перебираем всё и вешаем обработчик
for (let i = 0; i < paragraphs.length; i++) {
// собственно обработчик
paragraphs[i].onclick = function() {
this.style.color = "#FF0000";
}
}
}
// естественно, весь код должен работать после загрузки всей страницы
document.addEventListener("DOMContentLoaded", loader);
Данный код не является универсальным и написан с целью лишний раз подчеркнуть удобство использования jQuery ;)
jQuery, но ещё не плагин
Теперь можно этот код упростить, подключаем jQuery и получаем следующий вариант:
$(function(){
$('p').click(function(){
$(this).css('color', '#ff0000');
})
});
Таки jQuery-плагин
С поставленной задачей мы справились, но где тут повторное использование кода? Или если нам надо не в красный, а в зеленый перекрасить? Вот тут начинается самое интересное. Чтобы написать простой плагин, достаточно расширить объект $.fn
:
$.fn.mySimplePlugin = function() {
$(this).click(function(){
$(this).css('color', '#ff0000');
})
}
Если же писать более грамотно, то нам необходимо ограничить переменную $
только нашим плагином, а также возвращать this
, чтобы можно было использовать цепочки вызовов (т.н. «chaining»). Делается это следующим образом:
(function($) {
$.fn.mySimplePlugin = function() {
// код плагина
return this;
};
})(jQuery);
Добавим опцию по выбору цвета и получим рабочий плагин:
(function($) {
// значение по умолчанию - ЗЕЛЁНЫЙ
var defaults = { color:'green' };
// актуальные настройки, глобальные
var options;
$.fn.mySimplePlugin = function(params) {
// при многократном вызове настройки будут сохраняться и замещаться при необходимости
options = $.extend({}, defaults, options, params);
$(this).click(function() {
$(this).css('color', options.color);
});
return this;
};
})(jQuery);
Вызов:
// первый вызов
$('p:first').mySimplePlugin();
// второй вызов
$('p:eq(1)').mySimplePlugin({ color: 'red' });
// третий вызов
$('p:last').mySimplePlugin();
В результате работы данного плагина каждый клик будет изменять цвет параграфа на красный. Та как мы используем глобальную переменную для хранения настроек, то второй вызов плагина изменит значение для всех элементов:
Можно внести небольшие изменения и разделить настройки для каждого вызова:
// актуальные настройки будут индивидуальными при каждом запуске
var options = $.extend({}, defaults, params);
А разница-то в одном «var». Мне даже сложно себе представить, как много часов убито в поисках потерянного «var» в JavaScript. Будьте внимательны:
Работаем с коллекциями объектов
Тут всё просто, достаточно запомнить — this
содержит jQuery-объект с коллекцией всех элементов, т.е.:
$.fn.mySimplePlugin = function(){
console.log(this); // это jQuery объект
console.log(this.length); // число элементов в выборке
};
Если мы хотим обрабатывать каждый элемент, то соорудим следующую конструкцию внутри нашего плагина:
// необходимо обработать каждый элемент в коллекции
return this.each(function(){
$(this).click(function(){
$(this).css('color', options.color);
});
});
// предыдущий вариант немного избыточен,
// т.к. внутри функции click и так есть перебор элементов
return this.click(function(){
$(this).css('color', options.color);
});
Опять же напомню, если ваш плагин не должен что-то возвращать по вашей задумке — возвращайте this
. Цепочки вызовов в jQuery это часть магии, не стоит её разрушать. Методы each()
и click()
возвращают объект jQuery.
Публичные методы
Так, у нас написан «крутой» плагин, надо бы ему ещё докрутить функционала – пусть цвет регулируется несколькими кнопками на сайте. Для этого нам понадобится некий метод color
, который и будет в ответе за всё. Сейчас приведу пример кода готового плагина — будем курить вместе (обращайте внимание на комментарии):
// настройки со значением по умолчанию
var defaults = { color:'green' };
// наши будущие публичные методы
var methods = {
// инициализация плагина
init: function(params) {
// настройки, будут индивидуальными при каждом запуске
var options = $.extend({}, defaults, params);
// инициализируем лишь единожды
if (!this.data('mySimplePlugin')) {
// закинем настройки в реестр data
this.data('mySimplePlugin', options);
// добавим событий
this.on('click.mySimplePlugin', function(){
$(this).css('color', options.color);
});
}
return this;
},
// изменяем цвет в реестре
color: function(color) {
var options = $(this).data('mySimplePlugin');
options.color = color;
$(this).data('mySimplePlugin', options);
},
// сброс цвета элементов
reset: function() {
$(this).css('color', 'black');
}
};
$.fn.mySimplePlugin = function(method){
// немного магии
if ( methods[method] ) {
// если запрашиваемый метод существует, мы его вызываем
// все параметры, кроме имени метода прийдут в метод
// this так же перекочует в метод
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
// если первым параметром идет объект, либо совсем пусто
// выполняем метод init
return methods.init.apply( this, arguments );
} else {
// если ничего не получилось
$.error('Метод "' + method + '" в плагине не найден');
}
};
Теперь ещё небольшой пример использования данных методов:
// вызов без параметров - будет вызван init
$('p').mySimplePlugin();
// вызов метода color и передача цвета в качестве параметров
$('p').mySimplePlugin('color', '#FFFF00');
// вызов метода reset
$('p').mySimplePlugin('reset');
Для понимания данного кусочка кода вы должны разобраться лишь с переменной arguments
и методом apply()
. Тут им целые статьи посвятили, дерзайте:
Об обработчиках событий
Если ваш плагин вешает какой-либо обработчик, то лучше всего (читай – всегда) данный обработчик повесить в своём собственном namespace:
return this.on("click.mySimplePlugin", function(){
$(this).css('color', options.color);
});
Данный финт позволит в любой момент убрать все ваши обработчики или вызвать только ваш, что очень удобно:
// вызовем лишь наш обработчик
$('p').trigger("click.mySimplePlugin");
// убираем все наши обработчики
$('p').off(".mySimplePlugin");
— Дежавю? Ок!
На этом об обычных плагинах всё. Всем спасибо за внимание.
Last updated