jQuery. Базовый каркас для создания плагинов и виджетов

Категория: jQuery

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

Каркас jQuery плагина

Каркас простого jQuery плагина

$.fn.somePluginName = function() {
  this.css('color', 'red');
  return this;
}

Расширенный каркас jQuery плагина

(function ($) {
    'use strict';
    
    var privateVariable1 = 'Приватные..',
someVariable = '..переменные';

$.fn.somePluginName = function (options) {
var opts = $.extend( {}, $.fn.somePluginName.defaults, options ); return this.each(function() { // Обрабатываем все элементы коллекции });
}; $.fn.somePluginName.defaults = { config1: 'дефолтные настройки плагина', config2: 'дефолтные настройки плагина' }; }(jQuery));

Использование

$.fn.somePluginName.defaults.config1 = 'переопределяем базовые настройки плагина';

Каркас jQuery виджета

Идеологически, виджеты нужны для того, чтобы держать логику отображения и поведения некоторого блока в одном месте. Т.е. виджет должен отрендерить себя и обрабатывать события. Если результат обработки события, которое произошло внутри виджета, нужен другим виджетам - бросайте событие на документе. Либо же используйте callback ф-ции, которые можно передать в параметрах инициализации.

Идеально, если внутри jQuery виджета вы не лезете по DOM дереву за его пределы. Если лезете - скорее всего вам нужно применить событийную модель и бросать согласованные события.

Для лучшего понимания структуры виджета я создал demo (http://plnkr.co/zCNp2x), в этой песочнице можно поиграться с расширением и переопределением методов и поведения виджета.

Для использования виджетов вам необходим только компонент Widget из jQueryUI:


Что нужно знать при разработке jQuery виджета:

  • Формат именования виджетов: nameSpace.widgetName;
  • Базовые методы нашего виджета мы получаем от прототипа jQuery.Widget.prototype;
  • При инициализации виджета все опции прикрепляются к атрибуту data-<widgetname> каждого DOM элемента;
  • Экземпляр плагина напрямую связан с DOM элементом, т.е. вы можете получить экземпляр виджета по его DOM-элементу;
define(['domReady', 'jqueryUi'], function (domReady, $) {
    'use strict';

    $.widget('vendor.widgetName', {
        options: {
            someOption: null,
            afterClickCallback: function(e) {},
            beforeClickCallback: function(e) {}
        },

        _create: function() {
            this._bindEvents();
        },

        _setOptions: function(options) {
            // Вызывается при установке одной или набора опций
            // var widget = $('.class').data('vendor-widgetName');
            // widget.option('someOption', 'value');
            
            console.log('_setOptions');
            this._super(options);
        },

        _setOption: function(key, value) {
            // Вызывается для каждой переданной опции
            console.log('_setOption');
            this._super(key, value);
        },

        _bindEvents: function() {
            var self = this;

            this.element.on('click.widgetName', '.btnExample', function(e) {
                console.log('Click by btnExample');

                // Бросает событие для callback ф-ции переданной в опциях
                self._trigger('afterClickCallback', e, ['additionalData']);

                // Бросает событие для DOM элемента виджета
                self.element.trigger('afterClick', [slug, 2, 3]);
            });

            return this;
        },

        _destroy: function() {
            this.element.off('click.widgetName');
        }

    });
});
Внимание!

Обратите внимание, на позицию namespace при именовании виджета и событий. Имя виджета состоит из namespace.widgetName, тогда как в кастомном событии сначала идет название события, и уж потом неймспейс - eventType.namespace.

Примечание

Виджет предоставляет метод  _init(). Отличие этого метода от  _create() описано здесь - http://stackoverflow.com/questions/4566337/how-to-decide-between-init-and-create-in-jquery-ui-widget

Опции виджета

Перевод части документации... Одним из методов, которые автоматически доступны для виджета является option(). Этот метод позволяет прочитать и установить опции после инициализации виджета. Для получения значения опции необходимо указать только ее имя, для установки нового значения - передайте его вторым аргументом. Также вы можете передать хеш - чтобы установить набор необходимых опций.

Инициализация и использование виджета

Инициализировать виджет и получить его инстанс:

var widget = $('.el').widgetName({opt: 'val'}).data('vendor-widgetName');

События

Для обмена данными между виджетами удобно обмениваться событиями вместо того, чтобы искать DOM элемент, получать от него экземпляр виджета и вызывать какой-то метод. Виджеты должны быть автономными, а не зависимыми (хотя все зависит от контекста).

События генерируйте на всем DOM Document - так не нужно отслеживать перемещение виджетов по дереву DOM элементов. Нам не приходится хардкодить селекторы, которые указывают на виджет от которого нам нужно получить данные (слушать событие). Также не нужно передавать лишние параметры с селекторами при инициализации виджетов.

#plugin, #widget, #jQuery виджет, #примеры использования jQuery виджетов

категория: jQuery