2010-04-24 17 views
5

Conozco los diferentes modelos de eventos en Javascript (el modelo WC3 frente al modelo de Microsoft), así como la diferencia entre el borboteo y la captura. Sin embargo, después de unas horas de leer varios artículos sobre este tema, estoy todavía no está seguro cómo codificar correctamente el siguiente comportamiento aparentemente simple:Javascript: múltiples eventos de mouse desencadenados

Si tengo una externa div y un elemento interior div, quiero un solo ratón- evento externo que se activará cuando el mouse abandone el div externo. Cuando el mouse cruza desde el div interno hacia el div externo, nada debe pasar, y cuando el mouse cruza desde el div externo al div interno no debe pasar nada. El evento debe solo disparar si el mouse se mueve desde el exterior-div a la página circundante.

<div id="outer" style = "width:20em; height:20em; border:1px solid #F00" align = "center" onmouseout="alert('mouseout event!')" > 
<div id="inner" style = "width:18em; height:18em; border:1px solid #000"></div> 
</div> 

Ahora, si coloco el evento "mouseout" en el exterior-div, dos eventos mouseout se activa cuando el ratón se mueve desde el centro de la div que rodea a la página, porque se activa el evento una vez cuando el mouse se mueve de adentro hacia afuera, y luego otra vez cuando se mueve desde el exterior a la página circundante.

Sé que puedo cancelar el evento usando ev.stopPropagation(), así que intenté registrar un controlador de eventos con el inner-div para cancelar la propagación del evento. Sin embargo, esto no evitará que el evento se active cuando el mouse se mueva desde el div externo al div interno.

Así que, a menos que esté pasando por alto algo, me parece que este comportamiento no se puede lograr sin funciones complejas de rastreo de mouse. En el futuro, planeo volver a implementar mucho de este código usando un marco más avanzado, como JQuery, pero por ahora, me pregunto si existe una forma simple de implementar el comportamiento anterior en el Javascript normal.

+0

¿La página tal vez trata los elementos como combinados? Al igual que el div externo, sería simplemente "div externo" y luego el div interno dentro de él sería "external-div + inner-div", así que si se cruzan entre ellos, los tratará como dos separados, ambos con un evento onmouseout unido a ambos? Parece un poco extraño, pero parece ser la forma en que las páginas están trabajando aquí. – animuson

Respuesta

6

El evento mouseout en el interior div 'burbujas' a la división div. Para detectar que esto ha sucedido desde el div exterior, comprobar la propiedad target del event:

<div id="outer"> 
    <div id="inner">x</div> 
</div> 
document.getElementById('outer').onmouseout= function(event) { 
    // deal with IE nonsense 
    if (event===undefined) event= window.event; 
    var target= 'target' in event? event.target : event.srcElement; 

    if (target!==this) return; 
    ... 
}; 

El problema habitual con mouseout es que se consigue cuando el puntero se mueve “fuera” de la matriz incluso si solo se está moviendo "hacia adentro" hacia el niño. Puede detectar este caso manualmente por buscar la lista ancestro del elemento el ratón se está moviendo en:

var other= 'relatedTarget' in event? event.relatedTarget : event.toElement; 
    while ((other= other.parentNode).nodeType===1) 
     if (other===this) return; 

Este es el modelo mousein/mouseout: que sólo está interesado acerca de qué elemento es el padre inmediato del ratón. Lo que más a menudo desea es el modelo mouseenter/mouseleave, que considera los árboles de elemento como un todo, por lo que solo obtendría mouseleave cuando el puntero dejara el elemento o sus descendientes y no se moviera directamente al elemento o sus descendientes

Desafortunadamente mouseenter/mouseleave es actualmente un par de eventos solo de IE. Con suerte, otros navegadores lo recogerán, ya que se espera que forme parte de los eventos DOM Level 3.

Cuestiones relacionadas