Javascript.RU

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

Не доступна переменная vars в методе destroy
Не доступна переменная vars в методе destroy. Добрые люди подскажите что я делаю не так?

Вот кусок метода:
destroy: function() {
    alert(vars);// undefained
}


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

Вот сам плагин, описание внутри:
/* ------------------------------------------------------------------

Плаин выпадывающего меню .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                   Закрытие меню

Пример:
  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();
  
------------------------------------------------------------------ */

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

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

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

        // Стандартные настройка
        defaults = {
            button_element: 'a',
            menu_element: 'ul',
            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;

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

                    // Получение data настроек
                    data = $wrap.attr('data-dropdown');
                    if (data === undefined) {
                        data = {};
                    } else {
                        try {
                            data = JSON.parse(data);
                        } catch (error) {
                            $.error('Не верный формат JSON данных. В data атрибуте, для JQuery.dropdown');
                        }
                    }

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

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

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

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

                    $button.addClass(vars.button_class);

                    // Открытие закрытие меню
                    switch (vars.event) {
                        // При наведении
                        case 'hover':
                            $wrap.on('mouseenter.dropdow', 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(content) {
                // !!!
            },
            destroy: function() {
                var $wrap;

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

                alert(vars);// undefained
            }
        };

        // Вызов методов
        // Если запрашиваемы метод существует, вызываем его
        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) {
            element
                .addClass(vars.open_class)
                .trigger('open.dropdown');

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

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

            // Анимация
            switch (vars.animate) {
                case 'slide':
                    element
                        .children(vars.menu_element)
                        .slideUp(vars.animate_duraction);
                    break;
                case 'fade':
                    element
                        .children(vars.menu_element)
                        .fadeOut(vars.animate_duraction);
                    break;
                default:
                    element
                        .children(vars.menu_element)
                        .css('display', 'none');
                    break;
            }
        }
    };
}(jQuery));
Ответить с цитированием
  #2 (permalink)  
Старый 04.12.2015, 14:07
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Сообщение от Алексей Петрович
Не доступна переменная vars в методе destroy.
потому что при запуске плагина vars формируется каждый раз заново.
вариант ...
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
     $(function(){
     /* ------------------------------------------------------------------

Плаин выпадывающего меню .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                   Закрытие меню

Пример:
  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();

------------------------------------------------------------------ */

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

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

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

        // Стандартные настройка
        defaults = {
            button_element: 'a',
            menu_element: 'ul',
            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;

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

                    // Получение data настроек
                    data = $wrap.data('dropdown');
                    if (data) return ; //инициализация уже была

                    // Обьеденияем стандартные и пользовательские настройки
                    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('dropdown.render');

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

                    $button.addClass(vars.button_class);

                    // Открытие закрытие меню
                    switch (vars.event) {
                        // При наведении
                        case 'hover':
                            $wrap.on('mouseenter.dropdow', 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(content) {
                // !!!
            },
            destroy: function() {
                var $wrap, vars;

                // Обёртка
                $wrap = $(this);
                vars = $wrap.data('dropdown');
                console.log(vars)
                alert(vars);// undefained
            }
        };

        // Вызов методов
        // Если запрашиваемы метод существует, вызываем его
        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) {
            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) {
            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));
$(".menu").DropDown({event: ''})
.DropDown('destroy');
});


  </script>
</head>

<body>
<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>

</body>

</html>
Ответить с цитированием
  #3 (permalink)  
Старый 04.12.2015, 20:56
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

data = $wrap.data('dropdown');
if (data) return; //инициализация уже была


Меня пугает эти строчки, в особенности if (data) return;, это полностью убило возможность задавать настройки плагина в HTML, а это очень плохо.

Или может я что то путаю, посмотрел HTML а я кажется не знаю что делает .data(), почему в html нет data-dropdown=""?
А что делает строчка .stop(true, true), в анимации, что это?
Ответить с цитированием
  #4 (permalink)  
Старый 04.12.2015, 20:59
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

А зачем в самом начале $(function(){ если уже есть ;(function ($) {? Что это даёт?
Ответить с цитированием
  #5 (permalink)  
Старый 04.12.2015, 21:25
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Сообщение от Алексей Петрович
Меня пугает эти строчки, в особенности if (data) return;, это полностью убило возможность задавать настройки плагина в HTML, а это очень плохо.
переделайте так как вам нужно
Сообщение от Алексей Петрович
.stop(true, true),
при hover без этого будет глюк - остановка предыдущей анимации
Сообщение от Алексей Петрович
Что это даёт?
даёт гарантию что html сформировано а ваш код позволяет только коректно проинициализировать плагин -- можно вынести код плагина выше оставив только инициализацию строки 228 -229
Ответить с цитированием
  #6 (permalink)  
Старый 04.12.2015, 21:33
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

Сообщение от рони Посмотреть сообщение
переделайте так как вам нужно

при hover без этого будет глюк - остановка предыдущей анимации

даёт гарантию что html сформировано а ваш код позволяет только коректно проинициализировать плагин -- можно вынести код плагина выше оставив только инициализацию строки 228 -229
Обязательно, переделаю.

Вот про hover глюк, это да. Часто это вижу, жудко бесит, с click такая же ерунда, если раз 5 за секунду нажать. Огромное спасибо, за такую полезную штуку.

"можно вынести код плагина" - Посути это и так вынесено, и даже в отдельный файл.
Ответить с цитированием
  #7 (permalink)  
Старый 04.12.2015, 21:49
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Сообщение от Алексей Петрович
возможность задавать настройки плагина в HTML,
вариант
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>

     /* ------------------------------------------------------------------

Плаин выпадывающего меню .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                   Закрытие меню

Пример:
  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();

------------------------------------------------------------------ */

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

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

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

        // Стандартные настройка
        defaults = {
            button_element: 'a',
            menu_element: 'ul',
            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;

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

                    // Получение data настроек
                    data = $wrap.data('dropdown');
                    if (!data) data = {} ;
                    if (data.init) return ;  //инициализация уже была
                    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('dropdown.render');

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

                    $button.addClass(vars.button_class);

                    // Открытие закрытие меню
                    switch (vars.event) {
                        // При наведении
                        case 'hover':
                            $wrap.on('mouseenter.dropdow', 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(content) {
                // !!!
            },
            destroy: function() {
                var $wrap, vars;

                // Обёртка
                $wrap = $(this);
                vars = $wrap.data('dropdown');
                console.log(vars)
                alert(vars);// undefained
            }
        };

        // Вызов методов
        // Если запрашиваемы метод существует, вызываем его
        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) {
            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) {
            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;
            }
        }
    };
$(function(){
  $("[data-dropdown]").DropDown() //автозапуск плагина
});

}(jQuery));


$(function(){
//$(".menu").DropDown()
//.DropDown('destroy');
});


  </script>
</head>

<body>
<div class="menu" data-dropdown='{"event":""}' >
      <a href="#">Открыть</a>
      <ul>
        <li><a href="#">Пункт 1</a></li>
        <li><a href="#">Пункт 2</a></li>
        <li><a href="#">Пункт 3</a></li>
      </ul>
    </div>

</body>

</html>
Ответить с цитированием
  #8 (permalink)  
Старый 04.12.2015, 21:51
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

То что надо спасибо.
Ответить с цитированием
  #9 (permalink)  
Старый 04.12.2015, 21:54
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Алексей Петрович,
сложно соблюсти правильный формат data-dropdown
рекомендую прогонять через
<script>
document.write(JSON.stringify({event:''}))
 </script>

кавычки важны тогда из дата получится сразу обьект
Ответить с цитированием
  #10 (permalink)  
Старый 04.12.2015, 21:57
Аватар для Алексей Петрович
Аспирант
Отправить личное сообщение для Алексей Петрович Посмотреть профиль Найти все сообщения от Алексей Петрович
 
Регистрация: 29.11.2015
Сообщений: 83

Я умею этим пользоваться.
Да и ктому же есть онлайн генераторы.

Ещё раз спасибо.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не перезаписываемая переменная vars += Орёл Общие вопросы Javascript 3 13.06.2010 16:09