2010-09-10 14 views
10

W bibliotece, z której korzystam, mam zadanie przesunięcia elementu na początek strony, gdy jest on przewracany. (Zwiększam jego rozmiar, więc muszę go zobaczyć, a następnie zmniejszam, gdy mysz się wyłączy).Przeniesienie aktywnego elementu traci wydarzenie mouseout w przeglądarce Internet Explorer

Biblioteka, której używam, ma schludne rozwiązanie, które używa appendChildren na aktywnym elemencie, aby przenieść go do końca, tak aby jego rodzic był dalej pod koniec domingu i z kolei na wierzchu.

Problem polega na tym, że uważam, że element, który się porusza, jest tym, nad którym unosi się nad wydarzeniem mouseout. Twoja mysz nadal znajduje się nad węzłem, ale zdarzenie mouseout nie jest uruchamiane.

Usunąłem funkcję, aby potwierdzić problem. Działa dobrze w firefoxie, ale nie w żadnej wersji IE. Używam jquery tutaj dla prędkości. Rozwiązania mogą być w zwykłym starym javascriptu, który będzie preferencją, ponieważ może potrzebować wrócić do strumienia.

Nie mogę używać z-index tutaj, ponieważ elementy są vml, biblioteka jest Raphael i używam wywołania toFront. Próbka użyciu UL/li pokazać problem w prosty przykład

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<script src="js/jquery.min.js" type="text/javascript"></script> 
<style> 
    li 
    { 
     border:1px solid black; 
    } 
</style> 
</head> 
<body> 
<ul><li>Test 1</li></ul> 
<ul><li>Test 2</li></ul> 
<ul><li>Test 3</li></ul> 
<ul><li>Test 4</li></ul> 
<script> 
$(function(){ 
    $("li").mouseover(function(){ 
     $(this).css("border-color","red"); 
     this.parentNode.appendChild(this); 
    }); 

    $("li").mouseout(function(){ 
     $(this).css("border-color","black"); 
    }); 
}); 
</script> 
</body> 
</html> 

Edit: Oto link do pasty js kosza, aby zobaczyć go w akcji. http://jsbin.com/obesa4

** Edytuj 2: ** Zobacz wszystkie komentarze na wszystkie odpowiedzi, zanim opublikujesz jako dużo więcej informacji.

+0

Nie mogę zrozumieć Twojego posta. chcesz, aby zdarzenie 'mouseout' było uruchamiane, gdy twoja mysz nadal znajduje się nad elementem? jakie jest twoje prawdziwe pytanie? – lincolnk

+0

A dla this.parentNode.appendChild (this) ;, próbujesz ponownie dodać istniejący element LI? Dlaczego nie dodać do niej klasy CSS zamiast dodawać/usuwać ten sam element za pomocą nowego CSS? Czy twój oryginalny kod obejmuje dodanie zupełnie nowego elementu z innego miejsca w UL, aby naśladować efekt "rozszerzonego" rozmiaru, o którym wspomniałeś na początku? – Gary

+0

Linkol Próbuję uzyskać przykładowy kod do pracy, np. Tak jak w firefox. Zdarzenie mouseout nie uruchamia się. Używam li elementów jako przykład. Jak mówię w moim poście, elementy są w rzeczywistości elementami VML. Więc rzeczy takie jak indeks z-z lub dodawanie klas nie zadziałają, chyba że ludzie mogą udowodnić, że są inni. – johnwards

Odpowiedz

12

Problemem jest to, że IE obsługuje mouseover inaczej, ponieważ zachowuje się jak mouseenter i mousemove połączone na elemencie. W innych przeglądarkach jest to tylko mouseenter.

Więc nawet po tym, jak twoja mysz dotarła do elementu docelowego i zmieniłeś jego wygląd i ponownie go przyporządkował do swojego rodzica mouseover nadal będzie strzelał za każdy ruch myszki, element zostanie ponownie przywrócony, co uniemożliwi innym programom obsługi zdarzeń być nazwanym.

Rozwiązaniem jest naśladować poprawnego mouseover zachowanie tak, że działania w onmouseover są wykonywane tylko raz.

$("li").mouseover(function() { 
    // make sure these actions are executed only once 
    if (this.style.borderColor != "red") { 
     this.style.borderColor = "red"; 
     this.parentNode.appendChild(this); 
    } 
}); 

Przykłady

  1. Extented demo of yours
  2. Example wykazanie różnicy między przeglądarkami mouseover (premia: rodzimy javascript)
+0

Genialny, dokładnie to, na co liczyłem, kiedy ustawiam nagrodę. Mój kod działa o wiele lepiej, teraz nie muszę się też o to kręcić. – johnwards

+0

Jestem galdem mogłem pomóc :) – galambalazs

+3

Oto prosty przykład w Raphael 2.0.2 http://jsfiddle.net/K2bSY/2/ dla osób napotykających ten sam problem przy użyciu toFront(), pokazując przykładową poprawkę używając Raphaela. Funkcja data() – user568458

0

To niewyraźne i wydaje się być tylko IE (ale tak samo jest z VML). Jeśli element nadrzędny ma określoną wysokość, możesz dołączyć handler z myszką do rodzica ... ale wygląda na to, że to nie zadziała w twojej sytuacji. Twoja najlepsza alternatywa to najechanie kursorem myszy na sąsiednie elementy, aby je ukryć:

$(function() 
{ 
    $("li").mouseover(function() 
    { 
     $("li").css("border-color", "black"); 
     $(this).css("border-color", "red"); 
     this.parentNode.appendChild(this); 
    }); 
}); 

Lub SVG. Możesz użyć z-index w SVG.

+0

Hmm, alternatywa jest tu moim zdaniem rozwiązaniem. Zasadniczo będę musiał wywołać funkcję resetowania na wszystkich pozostałych elementach po najechaniu myszką, która uruchomi animację zmniejszania. Jest bardzo przylegający, ale może działać. Na razie zagłosuję na tę odpowiedź i zobaczę, czy ktoś inny coś wymyśli. – johnwards

1

udało mi się dostać pracę z zagnieżdżonych div i imprezy mouseenter na nadrzędny:

<div id="frame"> 
    <div class='box'></div> 
    <div class='box'></div> 
    <div class='box'></div> 
    <div class='box'></div> 
</div> 
... 
$('#frame').mouseenter(function() { 
    $(".box").css("border-color", "black"); 
}); 

Oto wersja robocza użyciu Raphael:

http://jsfiddle.net/xDREx/

+0

Może to w ogóle zadziałać. Nic się nie dzieje, gdy mysz nad pudłami. – johnwards

+0

Czy próbowałeś link? Z jakiej przeglądarki korzystasz? Mam go do pracy w IE6, IE7 i IE8. – webXL

+0

Ooh mouseenter na rodzica, czyli w zasadzie to, co robisz. Który odpala reset. Miły. Jednak nie rozwiązuje podstawowego problemu utraconych wydarzeń. (Zdarzenie Click też!) Deffo jest warte o połowę 200 punktów. Gdybym mógł dostać element, by dostać się na szczyt bez przegranych wydarzeń, byłbym szczęśliwym człowiekiem. (JSFiddle musiał być na dole, działa świetnie) – johnwards

0

I zmodyfikowana odpowiedź @galambalazs', bo okazało się, że to nie powiodło się, gdybym naprawdę szybko unosił się nad elementami li, jak niektórzy elementów nadal zachowują efekt mouseover.

Wymyśliłem rozwiązanie, które usuwa stan zawisu na elementach, które nie wyzwoliły zdarzenia mouseover, przez wciśnięcie tych elementów do stosu, gdy tylko zostanie wywołane mouseover. W dowolnym momencie zarówno zdarzenie lub mouseoutmouseover wywołaniu I pop elementy z tej tablicy i usunąć style na niej:

$(function(){ 

    // Track any hovered elements 
    window.hovered = []; 

    $("li").mouseover(function() { 
     // make sure that these actions happen only once 
     if ($(this).css("border-color") != "red") { 
      resetHovered(); // Reset any previous hovered elements 
      $(this).css("border-color","red"); 
      this.parentNode.appendChild(this); 
      hovered.push(this); 
     } 
    }); 

    $("li").mouseout(function(){ 
     resetHovered(); // Reset any previous hovered elements 
    }); 

    // Reset any elements on the stack 
    function resetHovered() { 
     while (hovered.length > 0) { 
      var elem = hovered.pop(); 
      $(elem).css("border-color","black"); 
     } 
    } 
}); 

Przetestowałem tego roztworu z IE 11. Funkcjonalny przykład można znaleźć here.

Powiązane problemy