我可以通过 JavaScript 禁用 CSS: 悬停效果吗?

我试图通过 JavaScript 阻止浏览器使用 CSS 的 :hover效果。

我已经在 CSS 中设置了 aa:hover样式,因为我想要一个悬停效果,如果 JS 不可用的话。但是如果 JS 可用,我想用一个更平滑的 CSS 悬停效果来覆盖它(例如使用 jQuery 颜色插件)

我试过了:

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

我也试过它与 return false;,但它不工作。

这里是我的问题的一个例子: http://jsfiddle.net/4rEzz/。链接应该只是淡出没有变成灰色。

正如 fudgey 提到的,解决方案是使用 .css()重置悬停样式,但是我必须覆盖 CSS 中指定的每一个属性(参见此处: http://jsfiddle.net/raPeX/1/)。我正在寻找一个通用的解决方案。

有人知道怎么做吗?

附注: 我不想覆盖每一个风格,我已经设置为悬停。

163971 次浏览

I would use CSS to prevent the :hover event from changing the appearance of the link.

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

This simple CSS means that the links will always be black and not underlined. I cannot tell from the question whether the change in the appearance is the only thing you want to control.

Try just setting the link color:

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

Edit: or better yet, use the CSS, as Christopher suggested

You can manipulate the stylesheets and stylesheet rules themselves with 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);

Making the attributes !important and making this the very last CSS definition should override any previous definition, unless one is more specifically targeted. You may have to insert more rules in that case.

There isn’t a pure JavaScript generic solution, I’m afraid. JavaScript isn’t able to turn off the CSS :hover state itself.

You could try the following alternative workaround though. If you don’t mind mucking about in your HTML and CSS a little bit, it saves you having to reset every CSS property manually via 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');
)

This is similar to aSeptik's answer, but what about this approach? Wrap the CSS code which you want to disable using JavaScript in <noscript> tags. That way if javaScript is off, the CSS :hover will be used, otherwise the JavaScript effect will be used.

Example:

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

Use a second class that has only the hover assigned:

HTML

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

CSS

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

Now you can use Jquery to remove the class, for instance if the element has been clicked:

JQUERY

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

Hope this answer is helpful.

Actually an other way to solve this could be, overwriting the CSS with insertRule.

It gives the ability to inject CSS rules to an existing/new stylesheet. In my concrete example it would look like this:

//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 with my 4 years old original example: http://jsfiddle.net/raPeX/21/

I used the not() CSS operator and jQuery's addClass() function. Here is an example, when you click on a list item, it won't hover anymore:

For example:

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

I'd recommend to replace all :hover properties to :active when you detect that device supports touch. Just call this function when you do so as 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');
}
}
}
}
}
}