Kann ich einen CSS: Hover-Effekt über JavaScript deaktivieren?

99

Ich versuche zu verhindern, dass der Browser den :hoverEffekt des CSS über JavaScript nutzt .

Ich habe die aund a:hover-Stile in meinem CSS festgelegt, da ich einen Hover-Effekt möchte, wenn JS nicht verfügbar ist. Aber wenn JS ist verfügbar, möchte ich mit einem meiner CSS Hover - Effekt zu überschreiben glattere ein (mit dem jQuery Farbe zum Beispiel Plugin.)

Ich habe es versucht:

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

Ich habe es auch mit versucht return false;, aber es funktioniert nicht.

Hier ist ein Beispiel für mein Problem: http://jsfiddle.net/4rEzz/ . Der Link sollte nur verblassen, ohne grau zu werden.

Wie von fudgey erwähnt, besteht eine Problemumgehung darin, die Schwebestile mithilfe von zurückzusetzen, .css()aber ich müsste jede einzelne Eigenschaft, die im CSS angegeben ist, überschreiben (siehe hier: http://jsfiddle.net/raPeX/1/ ). Ich suche eine generische Lösung.

Weiß jemand, wie man das macht?

PS: Ich möchte nicht jeden Stil überschreiben, den ich für den Hover festgelegt habe.

meo
quelle

Antworten:

136

Ich fürchte, es gibt keine reine generische JavaScript-Lösung. JavaScript kann das CSS nicht deaktivieren:hover Status selbst .

Sie können jedoch die folgende alternative Problemumgehung ausprobieren. Wenn es Ihnen nichts ausmacht, ein wenig in HTML und CSS herumzuspielen, müssen Sie nicht jede CSS-Eigenschaft manuell über JavaScript zurücksetzen.

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');
)
Paul D. Waite
quelle
5
Diese Lösung gefällt mir besser als die Noscript-Lösungen, da dies funktioniert, wenn das CSS vollständig in externen Dateien enthalten ist, und auch beim Laden von Seiten, wenn das CSS zuerst geladen wird, das JS jedoch erst später. Die Verwendung von jQuery zur "schrittweisen Verbesserung" von Dingen führt häufig zu Seiten, die nicht gut funktionieren, wenn Sie vor dem Laden auf Inhalte klicken. Selbst mit einem schnellen Browser auf einem schnellen Link sehe ich das sehr oft.
Mr. Shiny und New
@Herr. Glänzend und neu: Ich stimme zu, das gefällt mir auch besser als meine Lösung! Ich bin nicht sicher, warum ich die Eleganz dieses zuvor nicht bemerkt habe ...
Josh
3
"Ich mag diese Lösung besser als die Noscript-Lösungen, weil dies funktioniert, wenn das CSS vollständig in externen Dateien enthalten ist" - ebenso die <noscript>Lösung. Sie setzen einfach <link>Tags in Ihre <noscript>anstelle von <style>Tags. Mit meiner Lösung können Sie jedoch alles in einer Stylesheet-Datei und nicht in mehreren Dateien behalten.
Paul D. Waite
Es ist nicht genau das, wonach ich gesucht habe, aber ich denke, diese Lösung ist der beste Kompromiss! Vielen Dank an euch alle
meo
Sie können denselben Stil auch mit einem anderen Namen kopieren und mit jquery alle Elemente dieser Klasse auswählen, die Klasse entfernen und durch die Kopierklasse ersetzen.
chepe263
14

Verwenden Sie eine zweite Klasse, der nur der Schwebeflug zugewiesen ist:

HTML

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

CSS

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

Jetzt können Sie die Klasse mit Jquery entfernen, beispielsweise wenn auf das Element geklickt wurde:

JQUERY

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

Hoffe diese Antwort ist hilfreich.

Kai Noack
quelle
3
plus 1. es ist nicht orthodox, aber es knackt das Problem auf eine ziemlich erhabene Weise.
Jim Tollan
11

Sie können die Stylesheets und Stylesheet-Regeln selbst mit Javascript bearbeiten

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

Wenn Sie die Attribute wichtig machen und dies zur allerletzten CSS-Definition machen, sollte jede vorherige Definition außer Kraft gesetzt werden, es sei denn, eine ist spezifischer ausgerichtet. In diesem Fall müssen Sie möglicherweise weitere Regeln einfügen.

Stephen P.
quelle
1
Oder Sie können alle Noscript-Regeln in einem Stylesheet zusammenfassen und dann das Stylesheet für Javascript deaktivieren.
Sean Hogan
2
Oder platzieren Sie Ihr Noscript-Stylesheet- <link>Tag in einem <noscript>Element? Das würde funktionieren, oder?
Paul D. Waite
1
Oder löschen Sie die "beleidigende" Regel: developer.mozilla.org/en/DOM/stylesheet.deleteRule
RoToRa
1
Sogar IE5 kann das. Die Methode wird anders aufgerufen, sollte aber funktionieren: msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx . Ich habe andere Browser nicht überprüft, aber ich würde vermuten, dass alle modernen Browser den Standard implementieren.
RoToRa
In Firefox bekomme ichError: The operation is insecure.
Alex W
11

Dies ähnelt der Antwort von aSeptik, aber was ist mit diesem Ansatz? Wickeln Sie den CSS-Code, den Sie mit JavaScript deaktivieren möchten, in <noscript>Tags ein. Auf diese Weise wird bei deaktiviertem :hoverJavaScript das CSS verwendet, andernfalls wird der JavaScript-Effekt verwendet.

Beispiel:

<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>
Josh
quelle
4

Ich habe den not()CSS-Operator und die addClass()Funktion von jQuery verwendet. Hier ist ein Beispiel: Wenn Sie auf ein Listenelement klicken, wird es nicht mehr schweben:

Beispielsweise:

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');
});
ColdTuna
quelle
3

Ich würde CSS verwenden, um zu verhindern, dass das Ereignis: hover das Erscheinungsbild des Links ändert.

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

Dieses einfache CSS bedeutet, dass die Links immer schwarz und nicht unterstrichen sind. Ich kann anhand der Frage nicht sagen, ob die Änderung des Erscheinungsbilds das einzige ist, was Sie steuern möchten.

Christopher Altman
quelle
Es ist gut, dass es einen Hover-Effekt gibt, wenn JS auf einem Client nicht verfügbar ist. Aber wenn es so ist, muss ich es überschreiben. Ich habe eine: hover-Klasse in meinem CSS festgelegt und möchte sie nur deaktivieren.
Meo
@meo: Sie können die CSS-Pseudo-Klassen nicht deaktivieren, aber Sie können sie überschreiben, indem Sie alle Linkstile so einstellen, dass sie dasselbe Erscheinungsbild / dieselben Parameter haben. Sowohl diese Antwort als auch meine Antwort tun dies auf unterschiedliche Weise.
Mottie
3

Ich würde empfehlen, alle :hoverEigenschaften zu ersetzen , :activewenn Sie feststellen, dass das Gerät Touch unterstützt. Rufen Sie diese Funktion einfach auf, wenn Sie dies tun 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');
          }
        }
      }
    }
  }
}
Shobhit Sharma
quelle
Funktioniert super für mich. Vielen Dank!
Inversion
1

Versuchen Sie einfach die Linkfarbe einzustellen:

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

Bearbeiten: oder noch besser, verwenden Sie das CSS, wie Christopher vorgeschlagen hat

Mottie
quelle
jsfiddle.net/raPeX Ich habe ein Beispiel gemacht. Es funktioniert, aber es ist irgendwie dumm, das zu tun. Ich müsste jeden CSS-Wert abrufen und als Stil hinzufügen. Es muss einen besseren Weg geben. Das will ich nicht machen. aber +1 für den Hinweis
meo
Hallo Meo, nein nein, mein Code oben zielte auf einen bestimmten Link ab, da ich dachte, dass Sie das wollten. Sie könnten es mehr verallgemeinern, indem Sie einfach verwenden, aanstatt zu ul#mainFilter asagen, ob dies das ist, was Sie meinen, oder sagen Sie, dass jeder Link auf der Seite eine andere Farbe hat?
Mottie
Ich habe Ihre Demo mit Kommentaren aktualisiert, um Ihnen zu zeigen, was ich meine: jsfiddle.net/raPeX/2
Mottie
Ich habe das schon danke. Aber das Problem ist, dass sich nicht nur die Farbe auf meinem Schwebeflug ändert, manchmal der Hintergrund, der Rand, manchmal sogar die Linienhöhe. Deshalb wäre es für mich einfacher, nur den Schwebeflug zu verhindern und jeden einzelnen Schwebeflug-Effekt zu überschreiben.
Meo
Teilweise Patch für diese Idee: Sie könnten eine CSS-Regel erstellen a.jsOverride:hover, die alle CSS-Eigenschaften überschreibt, sodass die JS diese jsOverrideKlasse nur zu allen Links hinzufügen müssen, wenn die Seite
geladen wird
1

Eine andere Möglichkeit, dies zu lösen, könnte darin bestehen, das CSS mit zu überschreiben insertRule.

Es bietet die Möglichkeit, CSS-Regeln in ein vorhandenes / neues Stylesheet einzufügen. In meinem konkreten Beispiel würde es so aussehen:

//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 mit meinem 4 Jahre alten Originalbeispiel: http://jsfiddle.net/raPeX/21/

meo
quelle