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));
|
|
04.12.2015, 14:07
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Сообщение от Алексей Петрович
|
Не доступна переменная 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>
|
|
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), в анимации, что это?
|
|
04.12.2015, 20:59
|
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 83
|
|
А зачем в самом начале $(function(){ если уже есть ;(function ($) {? Что это даёт?
|
|
04.12.2015, 21:25
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Сообщение от Алексей Петрович
|
Меня пугает эти строчки, в особенности if (data) return;, это полностью убило возможность задавать настройки плагина в HTML, а это очень плохо.
|
переделайте так как вам нужно
Сообщение от Алексей Петрович
|
.stop(true, true),
|
при hover без этого будет глюк - остановка предыдущей анимации
Сообщение от Алексей Петрович
|
Что это даёт?
|
даёт гарантию что html сформировано а ваш код позволяет только коректно проинициализировать плагин -- можно вынести код плагина выше оставив только инициализацию строки 228 -229
|
|
04.12.2015, 21:33
|
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 83
|
|
Сообщение от рони
|
переделайте так как вам нужно
при hover без этого будет глюк - остановка предыдущей анимации
даёт гарантию что html сформировано а ваш код позволяет только коректно проинициализировать плагин -- можно вынести код плагина выше оставив только инициализацию строки 228 -229
|
Обязательно, переделаю.
Вот про hover глюк, это да. Часто это вижу, жудко бесит, с click такая же ерунда, если раз 5 за секунду нажать. Огромное спасибо, за такую полезную штуку.
"можно вынести код плагина" - Посути это и так вынесено, и даже в отдельный файл.
|
|
04.12.2015, 21:49
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Сообщение от Алексей Петрович
|
возможность задавать настройки плагина в 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>
|
|
04.12.2015, 21:51
|
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 83
|
|
То что надо спасибо.
|
|
04.12.2015, 21:54
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Алексей Петрович,
сложно соблюсти правильный формат data-dropdown
рекомендую прогонять через
<script>
document.write(JSON.stringify({event:''}))
</script>
кавычки важны тогда из дата получится сразу обьект
|
|
04.12.2015, 21:57
|
|
Аспирант
|
|
Регистрация: 29.11.2015
Сообщений: 83
|
|
Я умею этим пользоваться.
Да и ктому же есть онлайн генераторы.
Ещё раз спасибо.
|
|
|
|