2013-10-27 3 views
0

Я пытаюсь создать «меню наведения» - вы наведите указатель мыши на заголовок, а затем под ним появится окно меню - я хочу, чтобы оно исчезло, когда вы переместите мышь за ее пределы.Неожиданное поведение «onmouseout» в «меню наведения»

взгляд: http://jsfiddle.net/kzJ8y/

Наведите указатель на 'STUFF' - появится ниже окно меню. Теперь начните медленно перемещать курсор мыши на нем - вниз - как только вы передадите первый элемент - он исчезнет! Это не желаемое действие.
Очевидно, мое onmouseout определения на #menuStuffDIV - и вы можете ясно видеть, с Firebug его размерами - что он принимает ширину и высоту всего списка -
так .... почему он срабатывает после переезда вниз от первого элемента списка? Курсор все еще находится внутри границ div - что здесь происходит?

+2

Вопрос название странно. –

+0

Хорошо, я поменяю его на скучный. –

+0

Его не о скучном по интересному, его о релевантности с вашей проблемой, чтобы вы могли получить лучшую помощь от других, потому что сам вопрос хорош. Зачем позволять ему получать негативы –

ответ

0

Mousing из слоя вызывает событие кипящим на дочерних элементах:

в навигационном слое на основе вам могут понадобиться знать, когда мышь покидает слой таким образом, что она может быть закрыта. Поэтому вы регистрируете обработчик события onmouseout для этого слоя. Тем не менее, пузырь событий приводит к тому, что этот обработчик события срабатывает, когда мышь оставляет любой элемент внутри слоя.

-------------- 
| Layer  |.onmouseout = doSomething; 
| -------- | 
| | Link | ----> We want to know about this mouseout 
| |  | | 
| -------- | 
| -------- | 
| | Link | | 
| | ----> | but not about this one 
| -------- | 
-------------- 
---->: mouse movement 

Других шоу пробка, что при перемещении мышей в слой, а затем на ссылку, браузер зарегистрировать событие MouseOut на слое! Это не имеет для меня большого смысла (мышь все еще находится в слое), но все браузеры согласны с этим.

Итак, как мы отвергаем любое мышь, которое не происходит, когда мышь фактически покидает слой?

function doSomething(e) { 
if (!e) var e = window.event; 
var tg = (window.event) ? e.srcElement : e.target; 
if (tg.nodeName != 'DIV') return; 
var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; 
while (reltg != tg && reltg.nodeName != 'BODY') 
    reltg= reltg.parentNode 
if (reltg== tg) return; 
// Mouseout took place when mouse actually left layer 
// Handle event 
} 

Сначала получите цель цели, т.е. элемент, из которого вышла мышь. Если целью является не DIV (слой), немедленно прекратите эту функцию, так как мышь, конечно же, не покинула слой.

Если цель - это слой, мы по-прежнему не уверены, оставила ли мышь слой или указала ссылку внутри слоя. Поэтому мы собираемся проверить связанный с ним объект/toElement, т. Е. элемент, к которому движется мышь.

Мы считываем этот элемент, а затем мы собираемся двигаться вверх по дереву DOM, пока мы не встретим цель события (т. Е. DIV) или элемент body.

Если мы сталкиваемся с целью, мышь перемещается к дочернему элементу слоя, поэтому мышь фактически не покидает слой. Мы останавливаем функцию.

Когда функция пережила все эти проверки, мы уверены, что мышь фактически покинула слой, и мы можем предпринять соответствующие действия (обычно делая слой невидимым).

MouseEnter и MouseLeave:

Microsoft имеет другое решение. Он создал два новых события mouseenter и mouseleave. Они почти такие же, как мышь и мышь, за исключением того, что они не реагируют на пузырьки событий.Поэтому они видят, что весь элемент HTML, на который они зарегистрированы, являются одним сплошным блоком и не реагируют на наведения и выходы внутри блока.

Таким образом, использование этих событий также решает нашу проблему: они реагируют только на мыши/выходы на элемент, на который они зарегистрированы.

В настоящий момент эти события поддерживаются только Explorer 5.5 в Windows и выше. Возможно, другие браузеры будут копировать эти события.

Так что лучше использовать мышь, а не мышь, поскольку это вызывает пузыри событий.

+0

Извините, это не тот желаемый результат - с этим после того, как вы попытаетесь переместиться в окно меню, оно исчезает. –

+0

Я тщательно проанализировал вашу проблему и выяснил решение. Я обновил свой ответ. Проверьте это. –

1

Если вы используете JQuery вы можете использовать MouseLeave событие на DIV:

http://jsfiddle.net/Kjdc5/

$('#menuStuff').mouseleave(function(){ 
    $('#menuStuff').hide(); 
});