Показать сообщение отдельно
  #11 (permalink)  
Старый 05.12.2015, 00:52
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

Я доделал свой плагин, прошу оценки, советов по модернизации.
/* ------------------------------------------------------------------

Плагин выпалывающего меню .DropDown()

Опции:
  button_element: 'a',             Ссылка на кнопку для открытия меню
  menu_element: 'ul',              Ссылка на дочернее меню
  event: 'hover',                  Событие для открытия меню hover или click
  animate: 'slide',                Название анимации none, fade или slide
  animate_duraction: 500,          Скорость анимации в миллисекундах
  open_class: 'open',              Класс для открытого меню
  wrap_class: 'dropdown',          Класс обёртки меню
  button_class: 'dropdown-button', Класс кнопки меню
  menu_class: 'dropdown-menu'      Класс по меню

События:
  render.dropdown                  Визуализация, добавление нужных стилей, классов
  open.dropdown                    Открытие меню
  close.dropdown                   Закрытие меню

Методы:
  init                             Вызывается по умолчанию, инициализирует плагин
  update                           Обновляет настройки плагина
  destroy                          Удаляет работу плагина

Пример:
  HTML:
    <div class="menu">
      <a href="#">Открыть</a>
      <ul>
        <li><a href="#">Пункт 1</a></li>
        <li><a href="#">Пункт 2</a></li>
        <li><a href="#">Пункт 3</a></li>
      </ul>
    </div>

  JS:
    $(".menu").DropDown();

P.S. Это меню изначально придумано для WordPress, но подойдёт практически для
чего угодно так как оно требует минимальной вёрстки, и очень хорошо настраивается.
  
------------------------------------------------------------------ */

;(function ($) {
    "use strict";

    $.fn.DropDown = function(method, options) {
        var defaults, methods;

        // Если не указаны пользовательские настройки
        if(options === undefined) {
            options = {};
            // Если пользователь не указал метод но указал свои настройки
            if(typeof method === 'object') {
                options = method;
            }
        }

        // Стандартные настройка
        defaults = {
            button_element: 'a',
            menu_element: 'ul',
            menu_width: '200px',
            event: 'hover',
            animate: 'slide',
            animate_duraction: 500,
            open_class: 'open',
            wrap_class: 'dropdown',
            button_class: 'dropdown-button',
            menu_class: 'dropdown-menu'
        };

        // Методы плагина
        methods = {
            init: function () {
                // Цикл по всем элементам
                return this.each(function () {
                    var $wrap, $button, $menu, data, vars;

                    // Обёртка меню
                    $wrap = $(this);

                    // Получение data настроек
                    data = $wrap.data('dropdown');
                    data = !data ? {} : data;

                    // Выходим если инициализация уже была
                    if (data.init) return false;
                    data.init = true;

                    // Обледенением стандартные и пользовательские настройки
                    vars = $.extend({}, defaults, data, options);
                    $wrap.data('dropdown', vars);

                    // Элементы меню
                    $button = $wrap.children(vars.button_element);
                    $menu = $wrap.children(vars.menu_element);

                    // Визуализация
                    $wrap
                        .addClass(vars.wrap_class)
                        .trigger('render.dropdown');

                    $menu
                        .addClass(vars.menu_class)
                        .css('display', 'none');

                    $button.addClass(vars.button_class);

                    // Открытие закрытие меню
                    switch (vars.event) {
                        // При наведении
                        case 'hover':
                            $wrap.on('mouseenter.dropdown', function () {
                                open($(this));
                            }).on('mouseleave.dropdown', function () {
                                close($(this));
                            });
                            break;
                        // При клике
                        default:
                            $button.on('click.dropdown', function () {
                                var $this_wrap = $(this).parent($wrap);

                                if($this_wrap.hasClass(vars.open_class)) {
                                    close($this_wrap);
                                } else {
                                    open($this_wrap);
                                }
                            });
                            // При клике вне меню закрываем его
                            $(document).on('click.dropdown', function (event) {
                                if ($(event.target).closest($wrap).length) return;
                                close($wrap);
                                event.stopPropagation();
                            });
                            break;
                    }
                });
            },
            update: function() {
                methods.destroy.apply(this, options);
                methods.init.apply(this, options);
            },
            destroy: function() {
                var $wrap, vars, $button, $menu;

                // Обёртка
                $wrap = $(this);

                // Настройки
                vars = $wrap.data('dropdown');

                // Элементы меню
                $button = $wrap.children(vars.button_element);
                $menu = $wrap.children(vars.menu_element);

                // Если плагин не инициализирован то выходим
                if (!vars) return false;

                // Удаляем классы\стили
                $wrap.removeClass(vars.wrap_class);
                $menu.removeClass(vars.menu_class)
                     .css('display', '');
                $button.removeClass(vars.button_class);

                // Отменяем события
                $wrap.off('.dropdown');
                $button.off('.dropdown');
                $(document).off('.dropdown');

                // Удаляю настройки плагина
                $wrap.data('dropdown', '');
            }
        };

        // Вызов методов
        // Если закрашиваемый метод существует, вызываем его
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        // Если передан объект или ничего, вызываем метод init
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        // Если метода не существует, выдаём ошибку
        } else {
            $.error('Метод с именем ' +  method + ' не существует для jQuery.dropdown');
        }

        // Функция открытия меню
        function open(element) {
            var vars = element.data('dropdown');

            element
                .addClass(vars.open_class)
                .trigger('open.dropdown');

            // Анимация
            switch (vars.animate) {
                case 'slide':
                    element
                        .children(vars.menu_element)
                        .stop(true, true)
                        .slideDown(vars.animate_duraction)
                        .css('display', 'block');
                    break;
                case 'fade':
                    element
                        .children(vars.menu_element)
                        .stop(true, true)
                        .fadeIn(vars.animate_duraction)
                        .css('display', 'block');
                    break;
                default:
                    element
                        .children(vars.menu_element)
                        .css('display', 'block');
                    break;
            }
        }

        // Функция закрытия меню
        function close(element) {
            var vars = element.data('dropdown');

            element
                .removeClass(vars.open_class)
                .trigger('close.dropdown');

            // Анимация
            switch (vars.animate) {
                case 'slide':
                    element
                        .children(vars.menu_element)
                        .stop(true, true)
                        .slideUp(vars.animate_duraction);
                    break;
                case 'fade':
                    element
                        .children(vars.menu_element)
                        .stop(true, true)
                        .fadeOut(vars.animate_duraction);
                    break;
                default:
                    element
                        .children(vars.menu_element)
                        .css('display', 'none');
                    break;
            }
        }
    };
}(jQuery));
Ответить с цитированием