Не доступна переменная 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)); |
Цитата:
вариант ... <!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> |
data = $wrap.data('dropdown'); if (data) return; //инициализация уже была Меня пугает эти строчки, в особенности if (data) return;, это полностью убило возможность задавать настройки плагина в HTML, а это очень плохо. Или может я что то путаю, посмотрел HTML а я кажется не знаю что делает .data(), почему в html нет data-dropdown=""? А что делает строчка .stop(true, true), в анимации, что это? |
А зачем в самом начале $(function(){ если уже есть ;(function ($) {? Что это даёт?
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Вот про hover глюк, это да. Часто это вижу, жудко бесит, с click такая же ерунда, если раз 5 за секунду нажать. Огромное спасибо, за такую полезную штуку. "можно вынести код плагина" - Посути это и так вынесено, и даже в отдельный файл. |
Цитата:
<!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> |
То что надо спасибо.
|
Алексей Петрович,
сложно соблюсти правильный формат data-dropdown рекомендую прогонять через <script> document.write(JSON.stringify({event:''})) </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 Закрытие меню Методы: 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)); |
Алексей Петрович,
строка 160 // Если плагин не инициализирован то выходим if (!vars||(vars &&!vars.init)) return false; |
А что это значит?
|
Цитата:
|
Понятно.
Тут мне пришло в голову сделать, то что не когда не делал))) Управление с клавиатуры. 32 - Пробел 13 - Интер И тут возникла проблема, я хочу что бы меню открывалось по пробелу или интеру. $button.on('keypress.dropdown', [32, 13], function () { alert('пробел или интер'); }); Но почему то работает только пробел((( |
Алексей Петрович,
может keyup или keydown тогда? |
А какая по сути разница?
keypress - Нажатие клавиши, о налог keyup, полное нажатие клавиши keyup - Поднятие клавиши, когда отпустил клавишу keydown - Опускание клавиши, нажал но не отпустил Вот и вся разница, как будто они как то кардинально отличаются в своей работе. Я тут уже подумал, а как юзер поймет что что-то надо нажимать. Думаю по фокусу открывать меню, это просто. А вот с закрытием проблема, это как то надо отслеживать что нет дочерних элементов в фокусе. |
Пришла в голову мысль:
По фокусу открывать меню. Отслеживать нажатие tab в любом дочернем элементе. Если tab нажат на последнем focus'абельном элементе, то закрывать меню. Вообще возможно как то получить список focus'абельных элементов, что бы из него вытащить последний для условия? На такую мысль я набрел, после того когда вспомнил что плагин не имеет почти не каких привязанностей от вёрстки (Но может чуть-чуть) и следовательно общепринятое управление клавиатурой (пробел открыть, верх низ переключаться по меню) не возможно. Вот пример: http://jsfiddle.net/gasu9be5/7/, последний пункт меню я туда вообще поиск засунул. |
Алексей Петрович,
:victory: |
:(
|
Часовой пояс GMT +3, время: 19:57. |