El Modelo de Eventos del DOM
Revisa la recomendación oficial W3C DOM2 Event standard .Es debido a que los eventos del mouse tienen siempre como blanco al elemento
mas bajo en la jerarquía bajo el puntero del mouse. En este caso,
los eventos mouseout son disparados por los items del
menú, las etiquetas A, cuando mueves el mouse sobre ellas. Esto burbujea
hacia arriba a la etiqueta DIV del menú donde disparan el manejador
fijado para ello, llamando closeMenu() que oculta el menú.
Para evitarlo, hay que añadir cierto código a closeMenu()
para determinar hacia dónde se ha movido el mouse. Si se ha movido
dentro de un elemento contenido en la capa DIV del menú, debería
ignorar el evento. Sólo cuando se mueva a un elemento fuera de la
capa DIV del menú debería ocultarse éste.
Aquía está una versión actualizada de la función
closeMenu() que comprueba el objeto Event para
encontrar a qué elemento ha sido movido el mouse:
function closeMenu(event) {
var current, related;
if (window.event) {
current = this;
related = window.event.toElement;
}
else {
current = event.currentTarget;
related = event.relatedTarget;
}
if (current != related && !contains(current, related))
current.style.visibility = "hidden";
}
La variable related se fija al elemento al que se mueve el
mouse mientras que current es siempre la propia capa
DIV del menú. Si el elemento related es la propia capa
del menú u otro elemento dentro de ella en la jerarquía del
documento, el evento es ignorado. En otro caso, el menú se ocultará.
La función contains() ha sido añadida para
determinar si un elemento está contenido dentro de otro. El código
es el siguiente:
function contains(a, b) {
// Return true if node a contains node b.
while (b.parentNode)
if ((b = b.parentNode) == a)
return true;
return false;
}
Puedes probar la versión modificada con el link siguiente:
Ahora el menú tiene el comportamiento deseado, cerrándose sólamente cuando el mouse se ha movido completamnete fuera de él.
Conclusión
Ahora deberías tener una comprensión básica del modelo de eventos del DOM. Aunque hay algunos problemas en los que deberías reparar, mayormente causados por implementaciones especificas de los navegadores, puedes usar esta información para escribir código para el modelo estándar y resolver diferencias individuales entre navegadores con una cantidad de código minima.