jQuery — одна из наиболее часто используемых библиотек JavaScript, если не самая популярная, которая позволяет создавать замечательные вещи с помощью большого набора небольших инструментов, предлагаемых веб-разработчикам: манипулирование HTML / DOM, манипулирование CSS, методы событий HTML, эффекты и анимации, AJAX, утилиты,…
Одним из ключевых аспектов jQuery является возможность расширить его новыми функциями, так называемыми плагинами . Для тех, кто имеет базовые знания о jQuery и хочет или должен создать новый плагин jQuery, этот пост пытается стать кратким изложением полезных вещей, которые следует принять во внимание.
Прежде чем начать
Из-за гибкости и мощи языка сообщество Perl гордится своим девизом Tim Today :
Есть несколько способов сделать это
Вы можете рассмотреть то же самое для JavaScript, это правда. Тот факт, что JavaScript — это не объектно-ориентированный язык, а язык, основанный на прототипах, позволяет следовать парадигме ООП разными способами. В поисках кода шаблона для создания плагина jQuery я обнаружил множество тонн, но не все придерживались тех же соглашений и идей.
Здесь я представляю смесь наиболее приемлемых шаблонов и их ключевых аспектов.
Код
В дополнение к статье вы можете найти самодокументированную версию стандартного кода в моем репозитории GitHub .
Когда начать
Если вы планируете создать плагин jQuery, первое, что я предлагаю вам начать читать, это раздел « Плагины / авторинг » проектной документации. Это отличный стартовый ресурс, но в реальной жизни вы скоро обнаружите, что вам нужно знать немного больше об этом.
Использование плагина jQuery
Предположим, у нас есть плагин jQuery beautyLink
, который преобразует обычную ссылку ( <a>
элемент) в действительно приятную, изменяя семейство шрифтов, текст и цвет фона. Поэтому мы должны включить его в нашу страницу, прежде чем начать его использовать:
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery-beautylink.js"></script>
Обычный способ создать и применить его к элементу:
$('#linkID').beautyLink();
или, если вы хотите подать заявку на каждую ссылку текущей страницы:
$('a').beautyLink();
Позже, чтобы изменить цвет текста на красный, мы могли бы вызвать открытый метод плагина, например:
$('#linkID').beautyLink('color', 'red');
или чтобы получить текущий цвет текста:
$('#linkID').beautyLink('color');
то есть color
метод может действовать как установщик или получатель в зависимости от того, передали мы значение или нет.
Создание нового плагина
Хорошо, мы знаем, как использовать плагин, но мы хотим создать новый. Первый шаг, который нам нужно сделать, — это создать новый файл JavaScript, в котором будет размещен наш код. В качестве хорошей практики этот файл должен содержать раздел заголовка документации с именем плагина, версией, контактной информацией автора, лицензией и т. Д.
Когда мы включаем файл JavaScript в веб-страницу, нам нужно, чтобы код выполнялся автоматически, чтобы плагин мог быть зарегистрирован в jQuery. Для этого весь код JavaScript в файле должен быть внутри кода:
(function($, window, document, undefined) { // The code here })(jQuery, window, document);
Таким образом, код нашего плагина получит ссылку на библиотеку jQuery, окно и документ, а также неопределенную ссылку на undefined
параметр, который мы можем использовать для сравнения неопределенных значений (вау, это было слишком много неопределенных в предложение).
Функция обертки
Для создания плагина jQuery нам нужно зарегистрировать новую функцию в jQuery.fn
объекте. Это массив, в котором jQuery хранит ссылки на все доступные или включенные плагины на текущей странице. Чтобы добавить новый, просто напишите что-то вроде:
jQuery.fn.myPlugin = function(options) { // Do your awesome plugin stuff here };
или же
jQuery.fn['myPlugin'] = function(options) { // Do your awesome plugin stuff here };
Функция, которую вы определяете здесь, является точкой входа в ваш плагин. Это функция-обертка, которая должна обрабатывать инициализацию или вызов плагинов для любого метода плагина.
Как отличить действие?
Вопрос в том, как мы реализуем функцию-обертку плагина, чтобы различать, должна ли она инициализировать плагин или вызвать метод? Ответ в options
параметре.
Когда мы создаем плагин без передачи аргумента, options
параметр выглядит так undefined
:
$('#linkID').beautyLink();
Если мы создаем экземпляр любого аргумента, options
параметром является Object
:
$('#linkID').beautyLink({ someOption: 'a', someOther: 123 });
Наконец, если мы вызываем метод плагина как:
$('#linkID').beautyLink('color', 'red');
тогда options
параметр является массивом с двумя элементами['color', 'red']
Стартовый код для функции оболочки
Учитывая вышесказанное, мы можем написать базовый код для функции-оболочки:
$.fn[pluginName] = function(options) { var args = arguments; if (options === undefined || typeof options === 'object') { // Creates a new plugin instance } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { // Call a public pluguin method (not starting with an underscore) and different // from the 'init' one } };
Цепной или не цепной
jQuery известен (и мощен) своим цепным способом работы, то есть вызов метода возвращает ссылку на тот же элемент, поэтому мы можем сделать другой вызов. Например:
$('#someID') .parents(".pane") .animate({ opacity: "hide" }, "slow");
или применяется к нашему плагину:
$('#linkID') .beautyLink('color', 'red') .beautyLink('backgroundColor', 'black');
Мы должны думать, какие из наших методов должны быть цепными, а какие нет. Например, методы-получатели должны нарушать цепочечность . В нашем случае мы хотим позвонить:
$('#linkID').beautyLink('color');
возвращает red
значение, а не ссылку на элемент, чтобы сделать еще один вызов.
Реализация цепочки
Когда $.fn[pluginName]
вызывается функция-обертка, эта ссылка указывает на:
- выбранный элемент DOM, как при использовании:
$('#linkID').beautyLink('color', 'red');
или же
- список выбранных элементов DOM, например, при использовании:
$('a').beautyLink('color', 'red');
Следующий код показывает очень простую функцию-обертку, которая инициализирует экземпляр Plugin для каждого выбранного элемента. Это приводит к цепочечному вызову, который возвращает ссылку на тот же элемент, готовый сделать еще один цепочечный вызов:
$.fn[pluginName] = function(options) { return this.each(function() { new Plugin(this, options); }); }
Как избежать цепочечности
Решение о том, как избежать цепочки методов, легко, просто не пишет this.each()
и не выполняет код при первом появлении, то есть this[0]
.
Это будет более понятно в окончательном коде.
Функция jQuery.data ()
Мы используем $.data()
функцию в нашем коде, поэтому требуется краткое объяснение. Функция позволяет хранить произвольные данные на элементе (или получить это значение).$.data()
Это важно, потому что мы храним ссылку на экземпляр Plugin на каждом элементе, к которому он применяется. Это позволяет нам проверить, применил ли элемент плагин или нам нужно его создать. Это будет разъяснено в окончательном коде функции оболочки.
Код функции оболочки оболочки
Учитывая все вышесказанное, мы можем написать функцию-обертку нашего финального плагина. Подвести итоги:
- Если плагин вызывается без аргументов, то плагин инициализируется и ссылка сохраняется в элементе DOM.
- Если вызывается метод плагина и он не является методом получения, то метод называется поддержанием цепочки.
- Если вызывается метод плагина, и он является методом получения, тогда мы возвращаем значение и нарушаем цепочечность.
$.fn[pluginName] = function(options) { var args = arguments; if (options === undefined || typeof options === 'object') { // Creates a new plugin instance, for each selected element, and // stores a reference withint the element's data return this.each(function() { if (!$.data(this, 'plugin_' + pluginName)) { $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); } }); } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { // Call a public pluguin method (not starting with an underscore) for each // selected element. if (Array.prototype.slice.call(args, 1).length == 0 && $.inArray(options, $.fn[pluginName].getters) != -1) { // If the user does not pass any arguments and the method allows to // work as a getter then break the chainability so we can return a value // instead the element reference. var instance = $.data(this[0], 'plugin_' + pluginName); return instance[options].apply(instance, Array.prototype.slice.call(args, 1)); } else { // Invoke the speficied method on each selected element return this.each(function() { var instance = $.data(this, 'plugin_' + pluginName); if (instance instanceof Plugin && typeof instance[options] === 'function') { instance[options].apply(instance, Array.prototype.slice.call(args, 1)); } }); } } };
Примите во внимание, что мы также определили массив, в котором указывается, какой метод может действовать как получатель, когда они вызываются без каких-либо аргументов:
$.fn[pluginName].getters = ['someGetterMethod'];
Продолжение следует…
Мы рассмотрели основы создания плагина jQuery и узнали о важности функции-оболочки, которая является точкой входа в наш плагин.
В следующем посте я объясню, как мы можем организовать код нашего плагина, ответственного за реализацию функциональности, как создать приватный и публичный метод и т. Д.