2012-05-22 17 views
5

Ich habe ein mouseover-Ereignis, das einen Tooltip auslöst; Ich möchte, dass dieser Tooltip verschwindet, wenn die Maus entfernt wird. onmouseout funktioniert gut, außer, wenn das Element verschwindet.onmouseout nicht ausgelöst, wenn das Element verschwindet

Hier ist ein destilliertes Beispiel, das Hintergrund verwendet ändert anstelle von Tooltips (so können Sie es leicht laufen):

<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> 

Das Problem ist folgendes: wenn ich auf „mich entfernen“, ist meine Maus nicht mehr "over" das div, aber das onmouseout löst nicht aus, weil es weg ist. Ich möchte, dass dieses Beispiel auf einen weißen Hintergrund zurückkehrt, wenn ich auf "Remove me" klicke.

Es gibt eine offensichtliche Lösung, die ich gerne vermeiden würde. Ich möchte nicht, dass der onclick-Handler, der das Element entfernt, das Dokument manuell "repariert". Dies liegt daran, dass es beliebig viele Handler geben kann, die das div mit onmouseout entfernen könnten. Im Allgemeinen können alle Mouseout- und Entfernungshandler dynamisch erzeugt werden und müssen voneinander wissen. Um die Dinge noch weiter zu komplizieren, könnte ich einen Fall haben, bei dem entfernbare Elemente ineinander verschachtelt sind und alle von ihnen entfernt werden könnten. (Ich könnte in der Lage sein, diese Einschränkung zu entfernen, aber es wird eine wenig Arbeit.)


Hier ist ein Beispiel für eine Lösung, die funktionieren könnte: mit der Maus darüber, den modalen Dialog als „aktiv“ registrieren; Wenn alle Elemente entfernt sind, durchlaufen Sie alle modalen Dialoge und suchen Sie nach solchen, die sich nicht mehr im Dokument befinden. Aber das erfordert von mir, dass ich einen globalen Dialog aufbewahre, und brauche Zeit O (n * m), wobei n die Anzahl aktiver Dialoge ist und m wie tief verschachtelt der Dialog im DOM ist. Außerdem muss ich diese Operation immer ausführen, wenn ich Elemente entferne, selbst wenn es offensichtlich ist, dass nichts davon betroffen ist.

Hier ist eine andere Lösung, die funktionieren könnte: Wenn Sie ein onremovedrdfromdocument-Ereignis implementieren können, dann kopieren wir einfach den onmouseout-Handler zum onremovedrdfromdocument-Ereignis, und das Beispiel funktioniert auch korrekt. (Ich höre, dass jQuery dies unterstützen könnte, aber ich muss mit Nicht-jQuery-Code zusammenarbeiten.)

Hier ist noch eine andere mögliche Lösung: Lassen Sie jeden modalen Dialog wiederholt abfragen, um zu sehen, ob sein Elternteil im Dokument ist. Wenn es nicht ist, muss es Seppuku begehen. Aber Umfragen sind wirklich hässlich. (Ich denke, ich wäre bereit, dies zu tun, wenn es nichts Besseres gibt!)

Hier ist eine andere Idee: Verwenden Sie Ereigniserfassung, damit das OnMouseOut-Element zuerst das Klickelement erfassen und einen Timer einrichten, um zu überprüfen, ob es noch ist im Dokument, nachdem der Klick abgeschlossen ist.

Als Referenz hier ist, was ich wirklich versuche zu tun: Ich habe ein JS-Widget, das eine komplizierte Baumstruktur erstellt. Viele der Änderungen an dem Widget beinhalten das Klicken auf eine Schaltfläche in der Struktur, die dann aus der Struktur hinzufügt oder löscht (möglicherweise selbst löschen.) Einige der Knoten benötigen jedoch kompliziertere Bearbeitungsverfahren, daher möchte ich einen Tooltip anzeigen mit Anweisungen und möglicherweise mehr Schaltflächen, wenn der Benutzer über sie mousing, oder sogar den Dialog herum, wenn der Benutzer sie klickt. Aber der Benutzer kann seine Meinung ändern und entscheiden, den Knoten oder irgendein Elternteil des Knotens zu löschen, in welchem ​​Fall der Dialog weggehen sollte. Sie können eine Implementierung dessen anzeigen, was ich derzeit habe here, wo die Dialoge manuell erstellt werden. Ich würde gerne anfangen, eine nette Tooltip-Bibliothek zu benutzen, aber alle haben den Bug, den ich oben beschrieben habe.

+0

Gibt es einen Grund, warum Sie ein schließendes '' -Tag haben, wenn Sie kein entsprechendes Öffnen haben? Ihr Bereich ist auch ungültiger HTML-Code. Sie benötigen eine Schlussspanne. – Daedalus

+0

Sorry, es war ein Tippfehler. –

+0

Ihre Spanne ist weiterhin ungültig html. existiert nicht. – Daedalus

Antwort

0

Versuch:

<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

Diese Lösung schlägt den Modularitätstest fehl. Was wäre, wenn es in der Bar mehrere Onmouse-Handler gäbe? –

+0

Ich dachte, das OnmouseOutEvent, das gerufen wurde, war die Hoffnung. Sie können die Hintergrundfarbe einfach direkt ändern. Womit ich es bearbeitet habe. –

+0

Ihre Änderung hilft nicht, wenn der Hintergrund des ** Dokuments ** geändert wird; nicht der Inhalt der 'div' ** Leiste **. – Daedalus

2

Auf modernen Browsern gibt es das DOMNodeRemoved Ereignis. Also:

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

http://jsfiddle.net/HX88L/

Das Schlimme ist, ist das Ereignis bereits deprecated. Der Ersatz für die so genannte mutation events sieht noch nicht so aus, als ob sie schon fertig ist. Die MDN-Dokumentseite ist immer noch eine stub.

+0

Schön! Weißt du wie modern der Browser sein muss? Edit: Re, Missbilligung, das ist zum Kotzen! –

+0

Ich lese es funktioniert auf IE9, Chrome und Firefox - siehe http://Stackoverflow.com/a/6987471/825789 – bfavaretto

+0

Seltsamerweise, aus welchem ​​Grund auch immer, im vollständigen Beispiel funktioniert das nicht. Keine Ahnung warum. –

Verwandte Themen