Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   О наследовании событий, или как корректно его отменить. (https://javascript.ru/forum/events/7559-o-nasledovanii-sobytijj-ili-kak-korrektno-ego-otmenit.html)

JCShen 08.02.2010 08:36

О наследовании событий, или как корректно его отменить.
 
Вопрос родился по итогам стати Введение в события. Замечательная статья. Но задавшись элементарным вопросом, так и не смог реализовать его решение.

Смысл в следующем, создаем несколько вложенных слоев. (Как в примерах статьи) И на первый из них вешаем событие:

<style type="text/css">
.d1
{
	width:400px;
	height:400px;
	background:#0F0;
}

.d2
{
	width:300px;
	height:300px;
	background:#FF0000;
}

.d3
{
	width:200px;
	height:200px;
	background:#0000FF;
}
</style>

<div class="d1" id="d1" onmouseover="alert('test')">  
	<div class="d2" id="d2">  
		<div class="d3" id="d3"></div>  
	</div>  
</div>


Насколько я понял из стати div c id="d2" наследует событие от div c id="d1", и div c id="d3" наследует событие от div c id="d2"

Но вот как как ОСТАНОВИТЬ срабатывание события на "дочерних" к первому элементах, оставив по прежднему срабатывание алерта при событии на первом слое (с id="d1") на всей поверхности слоя, в т.ч. и перекрытой слоями d2 и d3.

Следующий JS код отменит срабатывание события для слоя d2 (и как следовательно для d3):

document.getElementById('d2').onmouseover = function(e)
{
	if (!e) e = event || window.event; // кросс-браузерно
	{
		e.cancelBubble = true;
		if (e.preventDefault) e.preventDefault();
	}
}

Но и для области слоя d1 перекрытому слоем d2 тоже отменит.

Обьясняя проще в IE с версии 5.5 была введена функция onmouseenter и она срабатывает именно так как мне и требуется. Но исползовать ее глупо. Т.к. решение не кроссбраузерное.

Очень надеюсь на помощь профессионалов. Если не примером кода то хотя бы тычком носом в статью или еще какой мануал. Где было бы разжевано как реализовать выше изложенное.

Мараторий 08.02.2010 08:47

Внутренние дивы не наследуют никаких событий.
Рассмотрим click. При нажатии на внутренний див браузер смотрит, есть ли обработчик на нем, если есть, то выполняет функцию.
Дальше событие всплывает и срабатывает на родителе этого дива. Потом всплывает дальше, и т.д.
При этом всплытие можно остановить.
Чтобы решить вашу задачу, необходимо проверять, на каком элементе сработало событие.

JCShen 08.02.2010 09:08

Все верно говорите, алерт будет срабатывать именно дойдя до того родителя на котором происходит событие. Если бы мне требовалось запускать какую то функцию по onClick я бы не стал беспокоить умных людей и задавать дурацкие вопросы. Только в приведеном мной примере проведя курсором от начала до конца первого слоя мы получим срабатывание события onMouseOver три раза. Т.е. Каждый раз когда пересекаем границу родительского и дочернего элемента.
Смысл и цель вопроса именно в том что бы функция срабатывала только один раз. А не три.

Мараторий 08.02.2010 10:35

Цитата:

Сообщение от Мараторий (Сообщение 43993)
Чтобы решить вашу задачу, необходимо проверять, на каком элементе сработало событие.

Для mouseover нужно проверять элементы срабатывания (откуда и куда)

JCShen 08.02.2010 11:01

Пример Кода ?

PeaceCoder 08.02.2010 15:03

То о чем вы говорите события moseenter и mouseleave/ Работают не везде.

JCShen 08.02.2010 17:17

Точнее работают только в IE, вот мне и нужно какое-то кросбраузерное решение. т.е. Своя обертка для этих двух функций.

PeaceCoder 08.02.2010 21:05

Скажу проще. Когда происходит событие onmouse* проверяйте содержит ли нужный элемент элемент target. Да - игнорируем, Нет - настоящее событие на входа/выхода стрелки
if (this===e.target || !this.contains(e.target)) {обрабатываем}

Ток еще надо подработать функцию .contains

JCShen 09.02.2010 00:00

Ок. Спасибо за совет... где то в этом направлении сейчас и думаю.


Часовой пояс GMT +3, время: 14:38.