onmouseenter lista imagenes eventos con javascript javascript-events

javascript - lista - onmouseover



¿Por qué no puedo capturar de manera confiable un evento de mouseout? (5)

Necesito saber cuándo el cursor del mouse deja un div . Así que mouseout evento mouseout . Sin embargo, si muevo el mouse muy rápido fuera de la div , el evento mouseout no se dispara . Así es: el cursor del mouse estaba todavía dentro del div , ahora está fuera del div y, sin mouseout no se ha llamado a la mouseout llamada del mouseout . (Funciona bien si no muevo el mouse muy rápido).

Esto es cierto en el último Google Chrome, por cierto, por lo que no es solo un problema de "navegadores antiguos".

Una solución:

Una pregunta sobre este problema ha sido planteada anteriormente . Aparentemente es solo un hecho de la vida, y la única solución que he encontrado es monitorear manualmente los eventos del mousemove , cada vez que mousemove coordenadas x / y del cursor y ver si caen dentro del cuadro delimitador del div , para que tenga más posibilidades de "notar" si el cursor ya no está dentro de él.

En comparación con dejar que el navegador haga todo esto de forma nativa, realizar cálculos en cada movimiento de píxel es un golpe de rendimiento. También es tedioso codificar.

En mi pregunta ...

¿Por qué el navegador no puede capturar de manera confiable el evento mouseout ? Si puedo decir de manera confiable cuándo el mouse dejó el div usando la solución anterior, ¿por qué el navegador no puede hacerlo?

Entiendo (de la respuesta vinculada anteriormente) que JavaScript no intenta interpolar "marcos". Digamos que si coloca un manejador de mousemove en el document y mueve rápidamente el mouse 200 píxeles hacia la derecha en una línea horizontal perfecta, es posible que no obtenga 200 eventos de mousemove . Algunos serán extrañados. No tengo un problema con eso.

Pero si se pierden algunos movimientos de píxel justo cuando el mouse cruza el límite del div , ¿por qué se sigue que el evento mouseout también se debe omitir? Cuando el navegador finalmente comienza a registrar la posición del mouse nuevamente (después de un movimiento rápido repentino), incluso si el mouse está ahora a millas fuera del cuadro, el punto es que solía estar en el cuadro y ya no está . Entonces, ¿por qué no dispara el evento mouseout entonces?

Simplemente no entiendo por qué este sería un problema difícil de resolver para los proveedores de navegadores. (Pero confío en que podría haber una buena razón, que soy demasiado estúpido para pensar).

Estoy publicando esta pregunta principalmente por curiosidad, pero espero que la respuesta me dé una idea que me podría ayudar a solucionar el problema de manera más eficiente. Además, cualquier solución alternativa (que sea más rápida que la presentada anteriormente) sería bienvenida.


  1. ¿Por qué el navegador no puede capturar de manera confiable el evento mouseout? Si puedo decir de manera confiable cuándo el mouse dejó el div usando la solución anterior, ¿por qué el navegador no puede hacerlo?

    Creo que respondiste a esto tú mismo cuando dijiste:

    En comparación con dejar que el navegador haga todo esto de forma nativa, realizar cálculos en cada movimiento de píxel es un golpe de rendimiento.

    El navegador no interpola entre los fotogramas, por lo tanto, como dijiste exigiría muchos más recursos y memoria, que puede ser el motivo por el cual no es "fijo".

  2. Si se pierden algunos movimientos de píxel justo cuando el mouse cruza el límite del div, ¿por qué se sigue que el evento mouseout también debe omitirse? Cuando el navegador finalmente comienza a registrar la posición del mouse nuevamente (después de un movimiento rápido repentino), incluso si el mouse está ahora a millas fuera del cuadro, el punto es que solía estar en el cuadro y ya no está. Entonces, ¿por qué no dispara el evento mouseout entonces?

    No lo sé con certeza, pero no creo que sea una condición de "estaba dentro y ahora está afuera". En cambio, es si cruza ese límite (si MouseX - ElemOffsetX= 1 ). Estoy de acuerdo, no tiene tanto sentido, pero podría ser porque si estableces el valor en > 1 , desencadenaría el evento varias veces. De lo contrario, tendría que hacer un seguimiento de los eventos, lo cual no está en la naturaleza de JS, ya que solo agrega eventos asincronizados a una pila.

Lo que podrías probar es usar el evento mouseleave de jQuery . Esto hace dos cosas, lo que retrasa el lanzamiento del evento:

  1. Atraviesa el árbol DOM para ver si realmente dejó el elemento
  2. Creo que implementa una llamada de tiempo de espera, que debería resolver el problema de interpolación que ha notado.

Encontré útil su pregunta y la falta de otras respuestas claras porque me dijeron que tenía que crear una solución alternativa. Lo hice usando las ideas presentadas en su pregunta y los otros colaboradores.

Tengo el mismo problema cuando uso jquery mouseleave elem.bind (''mouseleave'', data, mouseLeavesZone);

El problema es intermitente y puede estar relacionado con una CPU ocupada en el cliente. Digamos, por ejemplo, que la CPU está ocupada en otro lugar cuando el mouse se mueve fuera de un div. Entonces parece lógico que esta pueda ser la causa del error. Estoy de acuerdo; esto debería ser resuelto por los vendedores del navegador.

Ver http://jsfiddle.net/bgil2012/gWP5x/1/

(Aparte: mi código JQuery necesita usar métodos jQuery más antiguos porque tiene que ejecutarse en Drupal 7, que está ejecutando jQuery 1.4, en este momento y sin aplicar los parches que vienen).


Me encontré con este problema varias veces y llegué a aceptar el problema como un hecho de la vida. Pero depende de sus necesidades, puede usar CSS como yo lo hice. Por ejemplo, si solo quiero mostrar / ocultar una base de elemento en otro elemento que se encuentra suspendido, entonces CSS es el camino a seguir. Aquí hay un ejemplo útil y confiable:

.large { width: 175px; height: 175px; position: absolute; border-radius: 100%; /*hide the glass by default*/ top: -9999px; left: -9999px; opacity: 0; transition: opacity .2s ease-in-out; z-index: 100; pointer-events: none; } .small:hover + .large { opacity: 1; }

http://codepen.io/tanduong/pen/aBMxyd


Sé que no quiere una solución alternativa, pero no necesita verificar las x / y del mouse para saber si está dentro o fuera de un elemento. Simplemente puede verificar el elemento desde el cual se activó el evento mousemove. Si coloca un mousemove en el documento, el evento se disparará desde uno de sus elementos secundarios, y puede comparar ese elemento con su elemento para saber si es uno de sus descendientes.

O puede subir al árbol parentNode y detenerse si encuentra su elemento. Entonces sabrá que está dentro del elemento y aún está dentro de él, de lo contrario, llegará al documento y saldrá.

Algunos navegadores implementan los eventos mouseenter / mouseleave que, he notado, son más precisos que mouseout. Prototype y jQuery tienen una solución alternativa para los navegadores que no implementan estos nuevos eventos. Mouseleave no se activa desde los elementos de un elemento, mientras que mouseout sí.


Usted describe mover el mouse muy rápido. Cuando se detiene, ¿el puntero aún está dentro de la página? Es decir, ¿su puntero del mouse aún se encuentra sobre alguna parte de la página web visible?

Si se ha salido, entonces no está necesariamente claro qué debe hacer el navegador. El evento mouseout debe tener una propiedad relacionada de destino que se mouseout lo que ha introducido el puntero del mouse. Si el puntero del mouse ya está fuera del área de la página, no habría un objetivo relacionado al que apuntar.

Dicho de otra manera, cuando el mouse sale del área de la página, el navegador deja de rastrearlo y deja de informar su posición. Si mueves tu mouse lo suficientemente rápido, desde la perspectiva del navegador, el mouse simplemente desapareció. No es hasta que vuelva a colocar el mouse en el cuadro delimitador de la página visible que el navegador sabe dónde está, y luego desencadena todas las acciones apropiadas basadas en movimiento (como mouseout).