2012-05-22 19 views
5

Tengo un evento mouseover que desencadena una información sobre herramientas; Me gustaría que esta información sobre herramientas desaparezca cuando se quite el mouse. onmouseout funciona bien, excepto cuando el elemento desaparece.onmouseout no se activa cuando el elemento desaparece

Aquí está un ejemplo destilada que utiliza cambios de fondo en lugar de la información de herramientas (para que pueda ejecutar fácilmente):

<div id="bar"> 
    <div onmouseover="document.bgColor='gray'" onmouseout="document.bgColor='white'" style="border:1px solid black;"> 
    <span onclick="document.getElementById('bar').innerHTML = ''">Remove me</span> 
    </div> 
</div> 

El problema es el siguiente: cuando haga clic en "Eliminar yo", mi ratón ya no es "sobre" el div, pero el onmouseout no se dispara, porque se ha ido. Lo que me gustaría es que este ejemplo vuelva a un fondo blanco cuando hago clic en "Eliminarme".

Hay una solución obvia, que me gustaría evitar. No quiero que el controlador onclick que elimina el elemento "arregle" manualmente el documento. Esto se debe a que puede haber arbitrariamente muchos manejadores que podrían eliminar el div con onmouseout. En general, todos los manejadores de eliminación y eliminación de mouse se pueden generar dinámicamente y deben conocerse entre sí. Para complicar aún más las cosas, podría tener un caso en el que los elementos extraíbles estén anidados entre sí, y cualquiera de ellos podría eliminarse. (Que podría ser capaz de eliminar esta restricción, pero va a tomar un poco de trabajo.)


Aquí es un ejemplo de una solución que podría funcionar: por encima del ratón, se registra el diálogo modal como "activa"; luego, cada vez que se eliminan elementos, itere sobre todos los diálogos modales y busque los que ya no están en el documento. Pero esto requiere que tenga un almacén global de diálogos, y toma tiempo O (n * m), donde n es el número de diálogos activos, ym es qué tan anidado está el diálogo en el DOM. Además, necesito ejecutar esta operación cada vez que elimino elementos, incluso si es bastante obvio que nada se ve afectado.

Aquí hay otra solución que podría funcionar: si puede implementar un evento onremoved from document, entonces simplemente copiamos el controlador onmouseout para que sea el evento onremoved from document, y el ejemplo también funcionará correctamente. (He oído que jQuery podría soportar esto, pero necesito interoperar con código que no sea jQuery.)

Aquí hay otra posible solución: haga que cada diálogo modal haga sondeos repetidamente para ver si su padre está en el documento. Cuando no es así, haz que se comprometa seppuku. Pero las encuestas son realmente feas. (¡Supongo que estaría dispuesto a hacer esto si no hay nada mejor!)

He aquí otra idea: use la captura de eventos para permitir que el elemento onmouseout capture primero el elemento clic y configure un temporizador para verificar si todavía está en el documento después de hacer clic.


Para referencia, aquí es lo que realmente estoy tratando de hacer: Tengo un widget JS que construye una estructura de árbol complicada. Muchas de las ediciones del widget implican hacer clic en algún botón del árbol, que luego se agrega o elimina del árbol (posiblemente eliminándose). Sin embargo, algunos de los nodos necesitan procedimientos de edición más complicados, por lo que me gustaría mostrar una información sobre herramientas. con instrucciones y posiblemente más botones cuando el usuario pasa sobre ellos, o incluso mantiene el diálogo si el usuario hace clic en ellos. Pero el usuario puede cambiar de opinión y decidir eliminar el nodo o cualquier elemento primario del nodo, en cuyo caso el diálogo debería desaparecer. Puede ver una implementación de lo que actualmente tengo here, donde los diálogos se crean manualmente. Me gustaría comenzar a utilizar una buena biblioteca de información sobre herramientas, pero todos ellos tienen el error que describí anteriormente.

+0

¿Hay algún motivo por el que tenga una etiqueta de cierre ' 'cuando no tenga la correspondiente apertura? Tu lapso también es inválido html. Necesitas un lapso de cierre. – Daedalus

+0

Disculpa, fue un error tipográfico. –

+0

Su lapso sigue siendo html no válido. no existe. – Daedalus

Respuesta

0

intento:

<script> 
    var liveToolTip = new Array(); 
    function addLiveToolTip(elName){ 
     if(elName in liveToolTip){ 
     }else{ 
      liveToolTip[elName]=1;} 
    } 
    function removeLiveToolTip(elName){ 
     if(elName in liveToolTip){ 
      delete liveToolTip[elName]; 
     } 
    } 
    function runOnMouseOuts() { 
     for(mouseOut in liveToolTip) { 
      document.getElementById(mouseOut).onmouseout(); 
     } 
    } 
</script> 
<div id="bar"> 
    <div onmouseover="addLiveToolTip(this.id);document.bgColor='gray'" 
     onmouseout="removeLiveToolTip(this.id);document.bgColor='white'" style="border:1px solid black;" id="foo"> 
     <span onclick="document.getElementById('bar').innerHTML = '';runOnMouseOuts()"> 
     Remove me</span> 
    </div> 

+0

Esta solución falla la prueba de modularidad. ¿Qué pasa si hay varios controladores onmouseout dentro de la barra? –

+0

Pensé que llamar a onmouseoutevent era la esperanza. Alternativamente, puede cambiar el color de fondo directamente. Lo he editado para hacer. –

+0

Su edición no ayuda, teniendo en cuenta que se modificaron los antecedentes del ** documento **; no el contenido de la barra 'div' ** **. – Daedalus

2

En los navegadores modernos, no es el caso DOMNodeRemoved. Por lo tanto:

var div = document.getElementsByTagName('div')[0]; 
div.addEventListener('DOMNodeRemoved', function(e){ 
    document.bgColor='white'; 
});​ 

http://jsfiddle.net/HX88L/

Lo malo es, ese evento es ya deprecated. El reemplazo del llamado mutation events no parece que esté listo para usar todavía. La página de documentación de MDN sigue siendo solo stub.

+0

¡Agradable! ¿Sabes qué tan moderno debe ser el navegador? Editar: Re, desaprobación, eso es una mierda! –

+0

He leído que funciona en IE9, Chrome y Firefox - ver http://stackoverflow.com/a/6987471/825789 – bfavaretto

+0

Por extraño que parezca, por cualquier razón, en el ejemplo completo esto no funciona. No se por que. –

Cuestiones relacionadas