Pregunta

I'm trying to create a 'hover menu' - you hover the mouse over a title and then a menu box appears below it - I want it to disappear when you move the mouse outside of it.

look: http://jsfiddle.net/kzJ8y/

Hover over 'STUFF' - the menu box appears below. Now start moving the mouse cursor slowly on it - down - once you pass the first item - it disappears! This is not the desired action.
Clearly, my onmouseout definition is on the #menuStuff div - and you can clearly see with Firebug its dimensions - that it takes the width and height of the entire list -
so.... why does it fire after moving down from the first list item? The cursor is still inside the bounds of the div - what's going on here?

¿Fue útil?

Solución 2

Instead of onmouseout use onmouseleave:

<div id="menuStuff" class="hover-menu" onmouseleave="$('#menuStuff').hide();" >

jsfiddle -> http://jsfiddle.net/kzJ8y/1/

Otros consejos

If you are using jQuery you could use the mouseleave event on the div:

http://jsfiddle.net/Kjdc5/

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

Mousing out of a layer causes event bubbling on children elements:

In a layer-based navigation you may need to know when the mouse leaves a layer so that it can be closed. Therefore you register an onmouseout event handler to the layer. However, event bubbling causes this event handler to fire when the mouse leaves any element inside the layer, too.

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

Another show stopper is that when you move the mouse into the layer, and then onto a link, browsers register a mouseout event on the layer! It doesn't make much sense to me (the mouse is still in the layer), but all browsers agree on this one.

So how do we reject any mouseout that does not take place when the mouse actually leaves the layer?

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
}

First get the event target, ie. the element the mouse moved out of. If the target is not the DIV (layer), end the function immediately, since the mouse has certainly not left the layer.

If the target is the layer, we're still not sure if the mouse left the layer or entered a link within the layer. Therefore we're going to check the relatedTarget/toElement of the event, ie. the element the mouse moved to.

We read out this element, and then we're going to move upwards through the DOM tree until we either encounter the target of the event (ie. the DIV), or the body element.

If we encounter the target the mouse moves towards a child element of the layer, so the mouse has not actually left the layer. We stop the function.

When the function has survived all these checks we're certain that the mouse has actually left the layer and we can take appropriate action (usually making the layer invisible).

Mouseenter and mouseleave:

Microsoft has another solution. It has created two new events mouseenter and mouseleave. They are almost the same as mouseover and mouseout except that they don’t react to event bubbling. Therefore they see the entire HTML element they’re registered to as one solid block and don’t react to mouseovers and –outs taking place inside the block.

So using these events solves our problem too: they react only to mouseovers/outs on the element they’re registered to.

At the moment these events are only supported by Explorer 5.5 on Windows and higher. Maybe the other browser vendors will copy these events.

So It's best to use mouseleave rather than mouseout as it causes event bubbling.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top