2012-05-22 12 views
5

Mam zdarzenie mouseover, które uruchamia etykietkę narzędziową; Chciałbym, aby ta podpowiedź zniknęła po usunięciu myszy. onmouseout działa dobrze, z wyjątkiem, gdy element zniknie.onmouseout nie wyrzucony, gdy element zniknie

Oto przykład destylacji, która wykorzystuje tło zmienia zamiast podpowiedzi (dzięki czemu można łatwo go uruchomić):

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

Problem jest następujący: po kliknięciu „Usuń mnie” moja mysz nie jest już "over" div, ale onmouseout nie uruchamia, ponieważ odszedł. Chciałbym, aby ten przykład powrócił do białego tła po kliknięciu "Usuń mnie".

Istnieje oczywiste rozwiązanie, którego chciałbym uniknąć. Nie chcę obsługi instrukcji onclick, która usuwa element, aby ręcznie "naprawić" dokument. Dzieje się tak dlatego, że może istnieć dowolnie wiele procedur obsługi, które mogą usunąć div z funkcją onmouseout. Ogólnie, wszystkie procedury obsługi myszy i usuwania mogą być generowane dynamicznie i muszą się wzajemnie znać. Aby jeszcze bardziej komplikować sprawę, mógłbym mieć przypadek, w którym elementy wymienne są zagnieżdżone w sobie, a każdy z nich mógłby zostać usunięty. (Może być w stanie usunąć to ograniczenie, ale to zajmie trochę pracy.)


Tutaj jest przykładem rozwiązania, które mogłyby działać: po najechaniu myszą, należy zarejestrować modalne dialogu jako „aktywne”; wtedy, gdy elementy są usuwane, iteruj po wszystkich dialogach modalnych i szukaj tych, których już nie ma w dokumencie. Ale to wymaga ode mnie zachowania globalnego magazynu dialogów i zajmuje czas O (n * m), gdzie n jest liczbą aktywnych dialogów, a m jest tym, jak głęboko zagnieżdżone jest dialog w DOM. Co więcej, muszę uruchamiać tę operację za każdym razem, gdy usuwam elementy, nawet jeśli jest oczywiste, że nic nie dotyczy.

Oto inne rozwiązanie, które może działać: jeśli możesz zaimplementować zdarzenie onremovedfromdocument, to po prostu skopiujemy procedurę obsługi onmouseout jako zdarzenie onremovedfromdocument, a przykład będzie działał poprawnie. (Słyszałem, że jQuery może to wspierać, ale muszę współpracować z kodem nienależącym do jQuery.)

Oto jeszcze jedno możliwe rozwiązanie: niech każde modalne okno dialogowe będzie powtarzać ankietę, aby sprawdzić, czy jej rodzic znajduje się w dokumencie. Kiedy nie jest, niech to zrobi seppuku. Ale sondaże są naprawdę brzydkie. (Sądzę, że byłbym skłonny to zrobić, jeśli nie ma nic lepszego!)

Oto kolejny pomysł: użyj przechwytywania zdarzeń, aby element onmouseout przechwycił element kliknięcia jako pierwszy i ustaw zegar, aby sprawdzić, czy jest on nadal w dokumencie po zakończeniu kliknięcia.


Oto, co naprawdę próbuję zrobić: Mam widget JS, który buduje skomplikowaną strukturę drzewa. Wiele zmian w widgecie polega na kliknięciu jakiegoś przycisku w drzewie, który następnie dodaje lub usuwa z drzewa (prawdopodobnie sam się usuwa). Jednak niektóre węzły wymagają bardziej skomplikowanych procedur edycji, dlatego chciałbym wyświetlić etykietkę narzędzia z instrukcją i ewentualnie większą liczbą przycisków, gdy użytkownik myszkuje nad nimi, lub nawet utrzymuje dialog, jeśli użytkownik je kliknie. Ale użytkownik może zmienić zdanie i zdecydować się na usunięcie węzła lub dowolnego rodzica węzła, w którym to przypadku dialog powinien zniknąć. Możesz zobaczyć implementację tego, co aktualnie mam here, gdzie dialogi są tworzone ręcznie. Chciałbym zacząć korzystać z ładnej biblioteki podpowiedzi, ale wszystkie mają błąd, który opisałem powyżej.

+0

Czy istnieje powód, dla którego masz zamykający znacznik '', gdy nie masz odpowiadającego otworu? Twoje span jest również nieprawidłowe html. Potrzebujesz rozpiętości. – Daedalus

+0

Przepraszam, to był literówka. –

+0

Twoje span nadal jest nieprawidłowe html. nie istnieje. – Daedalus

Odpowiedz

0

try:

<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

To rozwiązanie nie przechodzi testu modułowości. Co by było, gdyby na pasku znajdowało się wiele instrukcji obsługi onmouseout? –

+0

Myślałem, że nazywa się onmouseoutevent, to była nadzieja. Możesz na przemian po prostu zmienić kolor tła bezpośrednio. Do czego to zredagowałem. –

+0

Twoja edycja nie ma znaczenia, ponieważ zmienia się tło ** dokumentu **; nie zawartość paska 'div' ** **. – Daedalus

2

W nowoczesnych przeglądarkach, nie jest zdarzeniem DOMNodeRemoved. Więc:

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

http://jsfiddle.net/HX88L/

Złą rzeczą jest to, że wydarzenie jest już deprecated. Zamiennik tak zwanego mutation events nie wygląda na gotowy do użycia. Strona dokumentu MDN wciąż jest tylko numerem stub.

+0

Nice! Czy wiesz, jak nowoczesna musi być przeglądarka? Edycja: Re, wycofanie, to jest do bani! –

+0

Przeczytałem, że działa na IE9, Chrome i Firefox - patrz http://stackoverflow.com/a/6987471/825789 – bfavaretto

+0

Co dziwne, z jakiegokolwiek powodu, w pełnym przykładzie to nie działa. Nie wiem dlaczego. –

Powiązane problemy