2009-05-11 12 views
7

Sto cercando di creare un semplice effetto mouseover usando una combinazione di mouseover, mouseout, addClass e removeClass. Fondamentalmente, quando l'utente ricopre un elemento, voglio applicare un bordo diverso (1px tratteggiato in grigio). Lo stato iniziale è "1px solido bianco". Ho una classe chiamata "highlight" che ha semplicemente "border: 1px dashed gray" in essa. Voglio aggiungere la classe onmouseover e rimuoverla su onmouseout ma non riesco a ottenere l'effetto che desidero a meno che non utilizzi! Importante nella classe "highlight".mouseover() mouseout() jQuery add/removeClass problem

+0

Potrebbe mostrare un po 'di codice? –

+1

BTW, Brian: dal momento che stai usando jQuery, potresti voler controllare il metodo helper dell'evento hover: http://docs.jquery.com/Events/hover – Shog9

risposta

14

Sembra che il javascript funzioni bene così com'è, ma è solo un problema con lo specificity of your CSS rules, che è il motivo per cui lo !important funziona.

Devi solo rendere le tue regole css evidenziate più specifiche delle regole non evidenziate.

#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;  
} 

Modifica con ulteriori spiegazioni:
Diciamo che le parti pertinenti del vostro HTML simile a questa:

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

e hai questo CSS:

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

Attualmente, tutte le voci dell'elenco nello ul in #someItem div avrà un bordo bianco e nulla ha la classe highlight quindi niente è grigio.

con qualsiasi mezzo che si desidera (nel tuo caso un evento hover in jQuery), si aggiunge una classe per una delle voci:

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

Il codice HTML sarà ora essere simile a questa:

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

Finora, Javascript e HTML funzionano correttamente, ma non vedi un bordo grigio! Il problema è il tuo CSS. Quando il browser sta tentando di decidere come stile l'elemento, esamina tutti i diversi selettori che hanno come target un elemento e gli stili definiti in quei selettori. Se ci sono due diversi selettori che definiscono lo stesso stile (nel nostro caso, il colore del bordo è contestato), allora deve decidere quale stile applicare e quali ignorare. Lo fa per mezzo di ciò che è noto come "Specificità" - cioè, quanto è specifico un selettore. Come indicato nello HTML Dog article, lo fa assegnando un valore a ciascuna parte del selettore e quello con il punteggio più alto vince. I punti sono:

  • selettore di elementi (ad esempio: "ul", "li", "tavolo") = 1 punto
  • selettore di classe (es: "EVIDENZA", ".active",". del menu ") = 10 punti
  • selettore di ID (ad esempio: "#someItem", "#mainContent") = 100 punti

ci sono alcune più regole, per esempio: la parola !important e anche stili inline, ma questo è per lo più irrilevante per questo, uhh ... "lezione". L'unica altra cosa che dovresti sapere è che se due selettori hanno la stessa specificità, vince quella definita in seguito nel file.

Tornando al tuo problema, dato il CSS che avevamo prima, possiamo vedere perché è ancora non ha un bordo grigio:

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

Come accennato in precedenza, la soluzione è quella di creare un selettore più specifico:

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

E per rispondere alla tua domanda nei commenti, non c'è bisogno di cambiare le tue JavaScript o HTML per far funzionare tutto questo.Se si spezza giù che il selettore, quello che sta dicendo è:

Cercare l'elemento con ID "someItem", all'interno di quello sguardo per un elemento ul, e poi un elemento li che ha la classe di "highlight" su di esso .

... e ora, data la semplice .addClass() chiamata che hai fatto in precedenza, i li soddisfa queste condizioni, in modo che il confine devono girare grigio.

+0

@nickf: Penso che tu stia facendo qualcosa qui. Come potrei usare il metodo addClass allora? Ho modificato la mia specificità ma ora, come faccio a fare riferimento alla classe in jQuery nel mio contesto? –

+0

Penso che il tuo jQuery sia a posto, basta usare .addClass ('highlight') e .removeClass ('highlight') dovrebbe essere tutto ciò che devi fare, se il tuo CSS è costruito correttamente. – nickf

+0

concordato. La regola CSS più specifica avrà la precedenza. Se si imposta la base con "#ItemList ul li", impostare lo stile hover con "#ItemList ul li.highlight" per garantire una maggiore specificità – Cheekysoft

1

Sto indovinando che si sta utilizzando uno stile in linea sull'elemento per lo stile iniziale:

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

Ciò sovrascrivere gli stili applicati utilizzando una classe ... Così, invece di utilizzare gli stili inline, solo utilizzare una classe iniziale diversa per applicare gli stili iniziali:

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

... 

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

Buon punto. Giusto per chiarire il caso, usando il metodo css() in jquery si applicano gli stili in linea. –

+0

Non sto usando gli stili in linea. Lo stile originale viene applicato tramite un foglio di stile con niente applicato tramite il tag o il metodo css(), ma l'aggiunta di un'altra classe tramite addClass() NON sostituirà una regola di stile già definita nello stile originale a meno che non utilizzi! Important. –

+0

Quindi assicurati che la regola per lo stile originale sia meno specifica o venga prima dello stile di evidenziazione nel foglio di stile. – Shog9

0

Avete considerato un approccio css puro?

Ad esempio:

someClass { 
    border: 1px solid white; 
} 

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

La classe hover pseudo vi darà il comportamento che si desidera: quando l'utente sta moused sopra l'elemento, userà lo stile più bassa, altrimenti userà il primo stile .

Nota: come qualcuno ha commentato, questo non funziona per gli elementi non a in IE. Funziona comunque per me in Chrome, Firefox, Safari e Opera.

Funziona anche per qualsiasi elemento in modalità standard IE8 e IE7. Non ho IE6 per testare però.

+0

Questo non funzionerà in IE6, credo. Solo un elemento può avere il passaggio del mouse al suo interno. –

+0

@Paolo Sembra funzionare in ogni browser oltre a IE per qualsiasi tipo di elemento. –

+0

Questo è quello che ho detto ...? D: –

0

Questo è un esempio di un hover ho usato:

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


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

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

non si ha realmente bisogno di rompere qualcosa questo semplice fino in funzioni separate.

Sospetto che il tuo problema potrebbe riguardare un conflitto nel css: prova ad applicare la tua classe di evidenziazione eseguendo l'hardcode o con un clic e verifica se funziona davvero.

Speranza che aiuta

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"); 
    } 
); 

faccio di solito in questo modo. (consente più opzioni)

+0

Questo è esattamente quello che sto facendo eccetto in div.target-hover I "border: 1px dashed grigio". Il bordo non sovrascriverà l'originale a meno che non aggiungo! Importante per qualche motivo. –

+0

è strano, come stai aggiungendo la prima classe all'elemento? –

+0

@Chad Proviene da una regola chiamata "#ItemList ul li" che ho impostato per avere "border: 1px solid white". Ho una classe chiamata "highlight" che ha semplicemente "border: 1px dashed gray" che voglio attivare. –

6

Da JQuery 1.3.3 sarete in grado di farlo un po 'più semplice. Ci sarà uno enhanced version of .toggleClass() disponibile che sarà molto potente.

Se non è necessario rompere questo fuori in una funzione poi da 1.3.3 sarete in grado di fare semplicemente:

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

Se hai includere importante allora il vostro punto culminante la classe potrebbe essere più specifica (vedi CSS Specificity).

0

Oppure si può semplicemente farlo con un semplice CSS utilizzando:

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

Non sono sicuro che sia una soluzione cross-browser (ancora), ma poi di nuovo, non ho mai detto che doveva essere. –