Posso disabilitare un effetto CSS: hover tramite JavaScript?


99

Sto cercando di impedire al browser di utilizzare l' :hovereffetto del CSS, tramite JavaScript.

Ho impostato gli stili ae a:hovernel mio CSS, perché voglio un effetto hover, se JS non è disponibile. Ma se JS è disponibile, voglio sovrascrivere il mio effetto hover CSS con uno più fluido (utilizzando il plug-in jQuery color ad esempio.)

Ho provato questo:

$("ul#mainFilter a").hover(
     function(e){ e.preventDefault(); ...do my stuff... }, 
     function(e){ e.preventDefault(); ...do my stuff... });

L'ho provato anche con return false;, ma non funziona.

Ecco un esempio del mio problema: http://jsfiddle.net/4rEzz/ . Il collegamento dovrebbe svanire senza diventare grigio.

Come accennato da fudgey, una soluzione alternativa sarebbe reimpostare gli stili di hover usando .css()ma dovrei sovrascrivere ogni singola proprietà, specificata nel CSS (vedi qui: http://jsfiddle.net/raPeX/1/ ). Sto cercando una soluzione generica.

Qualcuno sa come fare questo?

PS: non voglio sovrascrivere ogni stile che ho impostato per il passaggio del mouse.

Risposte:


136

Non esiste una soluzione generica JavaScript pura, temo. JavaScript non è in grado di disattivare il CSS:hover stato stesso.

Tuttavia, potresti provare la seguente soluzione alternativa. Se non ti dispiace fare un po 'di confusione nel tuo HTML e CSS, ti evita di dover reimpostare manualmente ogni proprietà CSS tramite JavaScript.

HTML

<body class="nojQuery">

CSS

/* Limit the hover styles in your CSS so that they only apply when the nojQuery 
class is present */

body.nojQuery ul#mainFilter a:hover {
    /* CSS-only hover styles go here */
}

JavaScript

// When jQuery kicks in, remove the nojQuery class from the <body> element, thus
// making the CSS hover styles disappear.

$(function(){}
    $('body').removeClass('nojQuery');
)

5
Mi piace questa soluzione meglio delle soluzioni noscript perché funziona quando il CSS è interamente contenuto in file esterni, e funziona anche durante il caricamento della pagina, se il CSS viene caricato prima ma il JS non viene caricato solo in un secondo momento. Usare jQuery per "migliorare progressivamente" le cose spesso si traduce in pagine che non funzionano bene se si fa clic su qualcosa prima che sia terminato il caricamento. Anche con un browser veloce su un collegamento veloce lo vedo spesso.
Mr. Shiny and New 安 宇

@Sig. Brillante e Nuovo: sono d'accordo, anche a me piace di più della mia soluzione! Non sono sicuro del motivo per cui non ho notato l'eleganza di questo prima ...
Josh

3
"Mi piace questa soluzione meglio delle soluzioni noscript perché funziona quando il CSS è interamente contenuto in file esterni", così come la <noscript>soluzione. Devi solo inserire i <link>tag all'interno del tuo <noscript>, invece dei <style>tag. La mia soluzione ti consente di mantenere tutto all'interno di un file di foglio di stile piuttosto che in più file.
Paul D. Waite,

non è esattamente quello che stavo cercando ma penso che questa soluzione sia il miglior compromesso! Grazie a tutti voi
meo

puoi anche copiare lo stesso stile con un nome diverso e usando jquery selezionare tutti gli elementi con quella classe e rimuovere la classe e sostituirla con la classe di copia.
chepe263

14

Usa una seconda classe a cui è assegnato solo il passaggio del mouse:

HTML

 <a class="myclass myclass_hover" href="#">My anchor</a>

CSS

 .myclass { 
   /* all anchor styles */
 }
 .myclass_hover:hover {
   /* example color */
   color:#00A;
 }

Ora puoi usare Jquery per rimuovere la classe, ad esempio se l'elemento è stato cliccato:

JQUERY

 $('.myclass').click( function(e) {
    e.preventDefault();
    $(this).removeClass('myclass_hover');
 });

Spero che questa risposta sia utile.


3
più 1. non è ortodosso, ma risolve il problema in modo sublime.
jim tollan

11

Puoi manipolare i fogli di stile e le regole dei fogli di stile con javascript

var sheetCount = document.styleSheets.length;
var lastSheet = document.styleSheets[sheetCount-1];
var ruleCount;
if (lastSheet.cssRules) { // Firefox uses 'cssRules'
    ruleCount = lastSheet.cssRules.length;
}
else if (lastSheet.rules) { / /IE uses 'rules'
    ruleCount = lastSheet.rules.length;
}
var newRule = "a:hover { text-decoration: none !important; color: #000 !important; }";
// insert as the last rule in the last sheet so it
// overrides (not overwrites) previous definitions
lastSheet.insertRule(newRule, ruleCount);

Rendere gli attributi! Importanti e rendere questa l'ultima definizione CSS dovrebbe sovrascrivere qualsiasi definizione precedente, a meno che una non sia specificatamente mirata. Potrebbe essere necessario inserire più regole in questo caso.


1
Oppure puoi mettere tutte le regole di noscript in un foglio di stile e quindi disabilitare il foglio di stile da javascript.
Sean Hogan

2
O inserire il <link>tag del foglio di stile noscript all'interno di un <noscript>elemento? Funzionerebbe, vero?
Paul D. Waite

1
Oppure elimina la regola "offensiva": developer.mozilla.org/en/DOM/stylesheet.deleteRule
RoToRa

1
Anche IE5 può farlo. Il suo metodo è chiamato in modo diverso, ma dovrebbe funzionare: msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx . Non ho controllato altri browser, ma immagino che tutti i browser moderni implementino lo standard.
RoToRa

In Firefox ottengoError: The operation is insecure.
Alex W

11

Questo è simile alla risposta di aSeptik, ma per quanto riguarda questo approccio? Avvolgi il codice CSS che desideri disabilitare utilizzando JavaScript nei <noscript>tag. In questo modo se javaScript è disattivato, :hoververrà utilizzato il CSS , altrimenti verrà utilizzato l'effetto JavaScript.

Esempio:

<noscript>
<style type="text/css">
ul#mainFilter a:hover {
  /* some CSS attributes here */
}
</style>
</noscript>
<script type="text/javascript">
$("ul#mainFilter a").hover(
     function(o){ /* ...do your stuff... */ }, 
     function(o){ /* ...do your stuff... */ });
</script>

4

Ho usato l' not()operatore CSS e la addClass()funzione di jQuery . Ecco un esempio, quando fai clic su un elemento dell'elenco, non si sposterà più:

Per esempio:

HTML

<ul class="vegies">
    <li>Onion</li>
    <li>Potato</li>
    <li>Lettuce</li>
<ul>

CSS

.vegies li:not(.no-hover):hover { color: blue; }

jQuery

$('.vegies li').click( function(){
    $(this).addClass('no-hover');
});

3

Vorrei usare CSS per evitare che l'evento: hover modifichi l'aspetto del collegamento.

a{
  font:normal 12px/15px arial,verdana,sans-serif;
  color:#000;
  text-decoration:none;
}

Questo semplice CSS significa che i collegamenti saranno sempre neri e non sottolineati. Non riesco a capire dalla domanda se il cambiamento nell'aspetto sia l'unica cosa che vuoi controllare.


è positivo che ci sia un effetto: hover se JS non è disponibile su un client. Ma se lo è, devo sovrascriverlo. Ho impostato una classe: hover nel mio css, voglio solo disabilitarla.
meo

@meo: non puoi disabilitare le classi CSS psuedo, ma puoi sovrascriverle impostando tutti gli stili di collegamento in modo che abbiano lo stesso aspetto / parametri. Sia questa risposta che la mia risposta lo fanno, solo in modi diversi.
Mottie

3

Ti consiglio di sostituire tutte le :hoverproprietà con :activequando rilevi che il dispositivo supporta il tocco. Chiama questa funzione quando lo fai come touch().

function touch() {
  if ('ontouchstart' in document.documentElement) {
    for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
      var sheet = document.styleSheets[sheetI];
      if (sheet.cssRules) {
        for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
          var rule = sheet.cssRules[ruleI];

          if (rule.selectorText) {
            rule.selectorText = rule.selectorText.replace(':hover', ':active');
          }
        }
      }
    }
  }
}

Funziona alla grande per me. Grazie!
Inversion

1

Prova a impostare il colore del collegamento:

$("ul#mainFilter a").css('color','#000');

Modifica: o meglio ancora, usa il CSS, come suggerito da Christopher


jsfiddle.net/raPeX ho fatto un esempio. Funziona ma è un po 'stupido farlo. dovrei recuperare ogni valore CSS e aggiungerli come stile? Deve esserci un modo migliore. Non voglio farlo. ma +1 per il suggerimento
meo

Ciao Meo, no no, il mio codice sopra era indirizzato a un link specifico perché è quello che pensavo volessi. Potresti generalizzarlo di più semplicemente usando ainvece di ul#mainFilter ase questo è ciò che intendi, o stai dicendo che ogni link sulla pagina è di un colore diverso?
Mottie

Ho aggiornato la tua demo, con commenti, per mostrarti cosa intendo: jsfiddle.net/raPeX/2
Mottie

L'ho già capito, grazie. Ma il problema è che non c'è solo il colore che cambia sul mio passaggio del mouse, a volte è lo sfondo, il bordo, a volte anche l'altezza della linea. Ecco perché sarebbe più facile per me impedire semplicemente hover, den per sovrascrivere ogni singolo effetto hover.
meo

Patch parziale per questa idea: potresti creare css una regola che seleziona per a.jsOverride:hoverche sovrascrive tutte le caratteristiche css, quindi js dovrebbe solo aggiungere quella jsOverrideclasse a tutti i link quando la pagina viene caricata ...
grossvogel

1

In realtà un altro modo per risolvere questo problema potrebbe essere sovrascrivere il CSS con insertRule.

Dà la possibilità di inserire regole CSS in un foglio di stile esistente / nuovo. Nel mio esempio concreto sarebbe simile a questo:

//creates a new `style` element in the document
var sheet = (function(){
  var style = document.createElement("style");
  // WebKit hack :(
  style.appendChild(document.createTextNode(""));
  // Add the <style> element to the page
  document.head.appendChild(style);
  return style.sheet;
})();

//add the actual rules to it
sheet.insertRule(
 "ul#mainFilter a:hover { color: #0000EE }" , 0
);

Demo con il mio esempio originale di 4 anni: http://jsfiddle.net/raPeX/21/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.