Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.09.2014, 15:29
Кандидат Javascript-наук
Отправить личное сообщение для vuler Посмотреть профиль Найти все сообщения от vuler
 
Регистрация: 16.02.2012
Сообщений: 109

Вопрос по идентичности 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.
Есть варианты решения, через создания обертки или использования классов, но думаю решение намного проще.
Ответить с цитированием
  #2 (permalink)  
Старый 02.09.2014, 17:17
Кандидат Javascript-наук
Отправить личное сообщение для vuler Посмотреть профиль Найти все сообщения от vuler
 
Регистрация: 16.02.2012
Сообщений: 109

В принципе нашел решение, но т.к. 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 и они разом вырубятся - это тоже не хорошо.
Ответить с цитированием
  #3 (permalink)  
Старый 02.09.2014, 19:36
Лаборант :-)
Отправить личное сообщение для Pavel M. Посмотреть профиль Найти все сообщения от Pavel M.
 
Регистрация: 08.11.2011
Сообщений: 806

Сообщение от vuler
Функцию обязательно надо обзывать, чтобы из ее тела ее можно было отрубить - $('body').off('click',jsksl);
Или можно как-то записать, чтобы не придумывать названия функций постоянно.
можно использовать в названиях событий namespace
например,
$( "form" ).on( "click.validator", ....);
$( "form" ).off( ".validator" );
почитайте, посмотрите самый нижний пример http://api.jquery.com/off/
Ответить с цитированием
  #4 (permalink)  
Старый 03.09.2014, 07:03
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 456

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');
	});
};
Ответить с цитированием
  #5 (permalink)  
Старый 03.09.2014, 08:46
Лаборант :-)
Отправить личное сообщение для Pavel M. Посмотреть профиль Найти все сообщения от Pavel M.
 
Регистрация: 08.11.2011
Сообщений: 806

Сообщение от vuler
для объекта боди может быть установленно несколько обработчиков событий
Сообщение от Rise
$(this).off('click');
эта строка удалить ВСЕ обработчики 'click' на document у всех подписчиков - за что их так?

пример http://learn.javascript.ru/play/UYhVe

Последний раз редактировалось Pavel M., 03.09.2014 в 08:50.
Ответить с цитированием
  #6 (permalink)  
Старый 04.09.2014, 17:16
Кандидат Javascript-наук
Отправить личное сообщение для vuler Посмотреть профиль Найти все сообщения от vuler
 
Регистрация: 16.02.2012
Сообщений: 109

Всем спасибо за советы.
Не знаю вот на правильном ли я пути теперь.
Присваиваю элементу уникальный номер, чтобы обработчик удалялся только для него. Вообще уникальности пока не много, т.к. в одну секунду может создаться несколько таких элементов с одинаковыми номерами. Вариант добавить - рандом к метке времени. Или сделать вообще массив где для каждой метки времени будут сохраняться все примененные рандомы, тогда будет действительно уникальное значение для каждого вызова функции.
Но может я опять полез в дебри и есть решение попроще? Может для каждого ДОМ элемента существует свой скрытый 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'));
	})
}
Ответить с цитированием
  #7 (permalink)  
Старый 04.09.2014, 21:37
Лаборант :-)
Отправить личное сообщение для Pavel M. Посмотреть профиль Найти все сообщения от Pavel M.
 
Регистрация: 08.11.2011
Сообщений: 806

а почему не нравился вариант отписки от события, когда вы давали функции имя jsksl и потом делали
$('body').off('click',jsksl);
??
Ответить с цитированием
  #8 (permalink)  
Старый 04.09.2014, 21:46
Кандидат Javascript-наук
Отправить личное сообщение для vuler Посмотреть профиль Найти все сообщения от vuler
 
Регистрация: 16.02.2012
Сообщений: 109

ну например на экране покажутся два блока
$('.div1').hide_by_click();
$('.div2').hide_by_click();

Тогда при клике на втором блоке. $('body').off('click',jsksl); отрубит обработчик и для первого блока.
В принципе выход есть путем хранения в памяти генератора имен, который увеличивает unic на единицу.
Ответить с цитированием
  #9 (permalink)  
Старый 04.09.2014, 22:26
Лаборант :-)
Отправить личное сообщение для Pavel M. Посмотреть профиль Найти все сообщения от Pavel M.
 
Регистрация: 08.11.2011
Сообщений: 806

Сообщение от vuler
Тогда при клике на втором блоке. $('body').off('click',jsksl); отрубит обработчик и для первого блока.
не отрубит, функция обработчик клика каждый раз создается новая при вызове .hide_by_click()

пример http://learn.javascript.ru/play/buCnwb

кликните пару раз в любом месте

в обработчике делаем $(this).off('click', jsksl); только для #test1

#test2 после этого нормально реагирует на клики

Последний раз редактировалось Pavel M., 04.09.2014 в 22:30.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DOM создание объекта JQ ~ вопрос реализации состояния Brook Events/DOM/Window 0 21.01.2014 22:45
Всплытие событий или что то не так... Кирюха =) jQuery 6 30.03.2013 12:56
Легкий вопрос по объекту DOM FRAGnat Events/DOM/Window 2 15.12.2012 21:09
вопрос по DOM Bogdan808 Общие вопросы Javascript 2 21.08.2010 18:54
Вопрос о циклических ссылках (JavaScript -> Dom -> JavaScipt) BlueIce Events/DOM/Window 10 17.02.2010 21:58