Вопрос по идентичности event.target и DOM
Всем доброго дня.
Делаю простой скрипт на JQuery. На экране выводится какое-то сообщение или показывается определенный блок и сразу же к нему применяем метод .hide_by_click(). При клике на область отличную от появившегося блока, он исчезает. Вот пример кода
function show_next_fadeToggle(){
fly_block=$(this).next();
fly_block.stop().fadeIn(500,function(){
$(this).hide_by_click();
});
jQuery.fn.hide_by_click=function(){
$('body').on('click',{elem:$(this)},function(e){
//alert(e.target);
//alert(e.data.elem);
//alert(fg.find(e.data.elem).length);
//alert(e.target.length);
if (e.target.length==e.data.elem.length){
alert('Клик на элементе');
}
//alert(e.target.find(e.data.elem).length);
if (e.data.elem.find(e.target).length!=0){
alert('Клик на элементе');
}else {//elem.remove();
}
})
}
В строке e.data.elem.find(e.target).length!=0 идет провека того, что элемент e.data.elem содержится в e.target(в то, по чему мы кликнули) Работает нормально, но вот когда клик производится по самому элементу, т.е. e.target равен e.data.elem начинаются проблемы. т.к. первый это objectHTMLDIVElement второй - object Object. Как сделать провеку что клик был именно по элементу e.data.elem. Есть варианты решения, через создания обертки или использования классов, но думаю решение намного проще. |
В принципе нашел решение, но т.к. javascript знаю не так хорошо, есть еще один маленький вопросик.
jQuery.fn.hide_by_click=function(){
$('body').on('click',{elem:$(this)},function jsksl(e){
if (e.data.elem.get(0)!=$(e.target).get(0) && e.data.elem.find($(e.target)).length==0){
e.data.elem.slideUp('500');
$('body').off('click',jsksl);
}
})
}
Вопрос в имени функции jsksl. Функцию обязательно надо обзывать, чтобы из ее тела ее можно было отрубить - $('body').off('click',jsksl); Или можно как-то записать, чтобы не придумывать названия функций постоянно. Плюс для объекта боди может быть установленно несколько обработчиков событий с функцией jsksl и они разом вырубятся - это тоже не хорошо. |
Цитата:
например, $( "form" ).on( "click.validator", ....); $( "form" ).off( ".validator" ); почитайте, посмотрите самый нижний пример http://api.jquery.com/off/ |
vuler,
jQuery.fn.hide_by_click = function(){
$(document).click({x:this},function(e){
if ($(e.target).closest(e.data.x).length) return;
e.data.x.fadeOut(500);
$(this).off('click');
});
};
|
Цитата:
Цитата:
пример http://learn.javascript.ru/play/UYhVe |
Всем спасибо за советы.
Не знаю вот на правильном ли я пути теперь. Присваиваю элементу уникальный номер, чтобы обработчик удалялся только для него. Вообще уникальности пока не много, т.к. в одну секунду может создаться несколько таких элементов с одинаковыми номерами. Вариант добавить - рандом к метке времени. Или сделать вообще массив где для каждой метки времени будут сохраняться все примененные рандомы, тогда будет действительно уникальное значение для каждого вызова функции. Но может я опять полез в дебри и есть решение попроще? Может для каждого ДОМ элемента существует свой скрытый ID номер, чтобы можно было их отличать?
function now_verbose(){
return new Date().getTime();
}
jQuery.fn.hide_by_click=function(){
unic=now_verbose();
$(this).attr('unic_id',unic);
$('body').on('click.'+unic,{elem:$(this)},function (e){
if ($(e.target).closest(e.data.elem).length) return;
e.data.elem.slideUp('500');
$('body').off('click.'+e.data.elem.attr('unic_id'));
})
}
|
а почему не нравился вариант отписки от события, когда вы давали функции имя jsksl и потом делали
$('body').off('click',jsksl); ?? |
ну например на экране покажутся два блока
$('.div1').hide_by_click();
$('.div2').hide_by_click();
Тогда при клике на втором блоке. $('body').off('click',jsksl); отрубит обработчик и для первого блока. В принципе выход есть путем хранения в памяти генератора имен, который увеличивает unic на единицу. |
Цитата:
пример http://learn.javascript.ru/play/buCnwb кликните пару раз в любом месте в обработчике делаем $(this).off('click', jsksl); только для #test1 #test2 после этого нормально реагирует на клики |
| Часовой пояс GMT +3, время: 07:00. |