2009-05-11 10 views
7

Próbuję utworzyć prosty efekt mouseover przy użyciu kombinacji mouseover, mouseout, addClass i removeClass. Zasadniczo, gdy użytkownik myszkuje nad elementem, chcę zastosować inną granicę (1 piksel przerywany na szaro). Początkowy stan to "1px solid white". Mam klasę o nazwie "highlight", która ma po prostu "border: 1px dashed grey". Chcę dodać tę klasę onmouseover i usunąć ją na onmouseout, ale nie mogę uzyskać pożądanego efektu, chyba że użyję! Ważne w klasie "highlight".mouseover() mouseout() jQuery dodaj/removeClass problem

+0

można pokazać jakiś kod? –

+1

BTW, Brian: ponieważ używasz jQuery, możesz wypróbować metodę helpera zdarzeń hover: http://docs.jquery.com/Events/hover – Shog9

Odpowiedz

14

Wygląda na to, że działa javascript bez zarzutu, ale jest to tylko problem z specificity of your CSS rules, dlatego też zadziała !important.

Wystarczy, że podkreślone reguły CSS będą bardziej szczegółowe niż zasady nie podświetlone.

#someItem ul li { /* Specificity = 102 */ 
    border-color: white; 
} 

.highlight { /* Specificity = 10 -- not specific enough! */ 
    border-color: grey;  
} 

#someItem ul li.highlight { /* Specificity = 112 -- this will work */ 
    border-color: grey;  
} 

Edit z dalszych wyjaśnień:
Powiedzmy odpowiednie części kodu HTML wyglądać następująco:

<div id="someItem"> 
    <ul> 
     <li>Item 1</li> 
     <li>Item 2</li> 
     <li>Item 3</li> 
    </ul> 
</div> 

i masz ten CSS:

#someItem ul li { 
    border: 1px solid white; 
} 
.highlight { 
    border-color: grey; 
} 

Obecnie wszystkie elementy listy w ul w #someItem div będzie mieć białą ramkę i nic nie ma klasy highlight, więc nic nie jest szare.

Przez co oznacza, że ​​chcesz (w przypadku zdarzenia najechania w jQuery), należy dodać klasę do jednej z pozycji:

$(this).addClass('highlight'); 

HTML będzie teraz wyglądać mniej więcej tak:

<div id="someItem"> 
    <ul> 
     <li>Item 1</li> 
     <li class="highlight">Item 2</li> 
     <li>Item 3</li> 
    </ul> 
</div> 

Do tej pory JavaScript i HTML działają poprawnie, ale nie widać szarej granicy! Problemem jest twój CSS. Kiedy przeglądarka próbuje zdecydować, jak stylizować element, analizuje wszystkie selektory, które celują w element i style zdefiniowane w tych selektorach. Jeśli istnieją dwa różne selektory, oba definiujące ten sam styl (w naszym przypadku kolor granicy jest kwestionowany), to musi zdecydować, który styl zastosować, a który zignorować. Czyni to za pomocą tak zwanej "Specyficzności" - czyli jak konkretny jest selektor. Jak opisano w HTML Dog article, robi to poprzez przypisanie wartości do każdej części selektora, a wygrywa ten, który uzyska najwyższy wynik. Punkty są:

  • selektor elementu (na przykład: "ul", "li" "stół") = 1 punkt
  • selektor klasy (na przykład: "HIGHLIGHT", ".active",”. menu ") = 10 punktów
  • selektor id (np: "#someItem", "#mainContent") = 100 punktów

Istnieje kilka zasad, np: słowo kluczowe !important a także style inline, ale to w większości nieistotne z tego, uhh ... "lekcja". Jedyną rzeczą, którą powinieneś wiedzieć, jest to, że jeśli dwa selektory mają tę samą specyfikację, to jedna zdefiniowana później w pliku wygrywa.

Wracając do Twojego problemu, biorąc pod uwagę CSS mieliśmy przed, widzimy, dlaczego to jeszcze nie ma granicy Szary:

 
#someItem ul li = id + element + element = 100 + 1 + 1 = 102 points 
.highlight = class = 10 points 

Jak wspomniano wcześniej, rozwiązaniem jest stworzenie bardziej szczegółowego wyboru:

 
#someItem ul li.highlight 
    = id + element + element + class 
    = 100 + 1 + 1 + 10 
    = 112 points 

I odpowiedzieć na pytanie w komentarzach, nie trzeba zmieniać żadnych JavaScript lub HTML dla tej pracy.Jeśli rozbić ten przełącznik, co ona mówi jest:

Look dla elementu o identyfikatorze „someItem”, wewnątrz, które wyglądają na ul elementu, a następnie element li, które posiada klasę „podświetlić” na nim .

... a teraz, ze względu na prosty .addClass() wezwanie, które wykonane wcześniej, li spełnia te warunki, więc granica powinna się szary.

+0

@nickf: Myślę, że coś tu masz. Jak mogę zatem użyć metody addClass? Zmieniłem swoją specyfikę, ale teraz, jak mogę odwołać się do klasy w jQuery w moim kontekście? –

+0

Myślę, że twój jQuery jest w porządku, po prostu używając .addClass ("highlight") i .removeClass ("highlight") powinno być wszystkim, co musisz zrobić, jeśli twój CSS jest poprawnie zbudowany. – nickf

+0

Uzgodnione. Najbardziej precyzyjna reguła CSS będzie miała pierwszeństwo. Jeśli ustawisz bazę za pomocą "#ItemList ul li", ustaw styl zawisu z "#ItemList ul li.highlight", aby zagwarantować wyższą specyfikację – Cheekysoft

1

Zgaduję używasz stylu inline na elemencie do początkowego stylu:

<style type="text/css"> 
    .hover { border: 1px dashed gray; } /* will never apply */ 
</style> 

... 

<!-- this style has priority over class styles! --> 
<div style="border: 1px solid white"> 
... 
</div> 

ten zastąpi style zastosowane przy użyciu klasy ... Więc zamiast używać stylów inline, po prostu użyj innej klasy początkowej, aby zastosować początkowe style:

<style type="text/css"> 
    .normal { border: 1px solid white; } 
    .hover { border: 1px dashed gray; } 
</style> 

... 

<div class="normal"> 
... 
</div> 
+0

Dobrze. Aby wyjaśnić pytanie pytającemu, użycie metody css() w jquery dotyczy stylów wbudowanych. –

+0

Nie używam stylów wbudowanych. Oryginalny styl zostanie zastosowany za pomocą arkusza stylów, w którym nic nie zostanie zastosowane za pomocą znacznika lub metody css(), ale dodanie innej klasy za pomocą metody addClass() NIE spowoduje przesłonięcia reguły stylu już zdefiniowanej w oryginalnym stylu, chyba że użyję! –

+0

Następnie upewnij się, że reguła dla oryginalnego stylu jest mniej dokładna lub występuje przed stylem podświetlenia w arkuszu stylów. – Shog9

0

Czy brałeś pod uwagę podejście czysto CSS?

Na przykład:

someClass { 
    border: 1px solid white; 
} 

someClass:hover { 
    border: 1px dashed gray; 
} 

Klasa hover pseudo daje zachowanie, które chcesz: gdy użytkownik moused nad elementem, użyje dolną styl, w przeciwnym razie użyje pierwszego stylu .

Uwaga: jak ktoś skomentował, to nie działa dla elementów innych niż a w IE. Działa to jednak dla mnie w Chrome, Firefox, Safari i Opera.

Działa również dla dowolnego elementu w trybie standardów IE8 i IE7. Nie mam jednak testu IE6.

+0

To nie zadziała w IE6, jak sądzę. Tylko elementy mogą zawierać w sobie wskaźnik. –

+0

@Paolo Wydaje się działać w każdej przeglądarce oprócz IE dla dowolnego typu elementu. –

+0

Tak powiedziałem ...? D: –

0

To jest przykład z zawisu Użyłem:

$(".myclass").hover(jbhovershow,jbhoverhide); 


jbhovershow = function() { 
      $(this).addClass("jimtest"); 
      }; 

jbhoverhide = function() { 
      $(this).removeClass("jimtest"); 
      } 

naprawdę nie musiał złamać coś tak prostego aż do oddzielnych funkcji.

Podejrzewam, że Twój problem może być związany z konfliktem w css - spróbuj po prostu zastosować klasę podświetlenia, wykonując ją na stałe, lub kliknij i sprawdź, czy naprawdę działa.

nadzieję, że pomoże

Jim

0

CSS:

div.target { 
    border: 1px solid #000000; 
} 

div.target-hover { 
    border-color: #ff0000; 
} 

JS:

$("div.target").hover(
    function() { 
     $(this).addClass("target-hover"); 
    }, 
    function() { 
     $(this).removeClass("target-hover"); 
    } 
); 

zwykle zrobić to w ten sposób. (pozwala na więcej opcji)

+0

To jest dokładnie to, co robię, z wyjątkiem div.target-hover Mam "border: 1px dashed szary". Granica nie zastąpi oryginału, chyba że dodam! Ważne z jakiegoś powodu. –

+0

To dziwne, jak dodajesz pierwszą klasę do elementu? –

+0

@Chad Pochodzi z reguły o nazwie "#ItemList ul li", która ma styl "border: 1px solid white". Mam klasę o nazwie "highlight", która po prostu ma "border: 1px dashed gray", którą chcę przełączać. –

6

Od Jquery 1.3.3 będziesz mógł to zrobić trochę prościej. Będzie dostępny enhanced version of .toggleClass(), który będzie bardzo wydajny.

Jeśli nie trzeba przerwać to na zewnątrz w zależności od 1.3.3 wtedy będziesz mógł po prostu zrobić:

$(".myclass").hover(function(){ $(this).toggleClass('highlight'); }); 

Jeśli masz na to ważne wówczas kulminacyjnym klasa może być bardziej specyficzna (patrz CSS Specificity).

0

Albo można po prostu zrobić to z prostego za pomocą CSS:

#namehere { border: 1px solid #fff; } 
#namehere:hover { border: 1px dashed #aaa } 
+1

Nie jestem pewien, czy jest to rozwiązanie oparte na różnych przeglądarkach (jeszcze), ale znowu, nigdy nie powiedziałem, że musi to być. –