我可以通过 JavaScript 禁用 CSS :hover 效果吗?
Posted
技术标签:
【中文标题】我可以通过 JavaScript 禁用 CSS :hover 效果吗?【英文标题】:Can I disable a CSS :hover effect via JavaScript? 【发布时间】:2011-02-14 19:43:12 【问题描述】:我试图阻止浏览器通过 javascript 使用 CSS 的 :hover
效果。
我在我的 CSS 中设置了 a
和 a: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/)。我正在寻找一个通用的解决方案。
有人知道怎么做吗?
PS:我不想覆盖我为悬停设置的所有样式。
【问题讨论】:
【参考方案1】:使用仅分配了悬停的第二个类:
HTML
<a class="myclass myclass_hover" href="#">My anchor</a>
CSS
.myclass
/* all anchor styles */
.myclass_hover:hover
/* example color */
color:#00A;
现在您可以使用 Jquery 删除该类,例如,如果元素已被单击:
JQUERY
$('.myclass').click( function(e)
e.preventDefault();
$(this).removeClass('myclass_hover');
);
希望这个答案有帮助。
【讨论】:
加1。它不是正统的,但以一种非常崇高的方式解决了问题。【参考方案2】:当您检测到该设备支持触摸时,我建议将所有 :hover
属性替换为 :active
。当你这样做的时候调用这个函数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');
【讨论】:
非常适合我。谢谢!【参考方案3】:我使用了not()
CSS 运算符和jQuery 的addClass()
函数。这是一个示例,当您单击列表项时,它不会再悬停:
例如:
<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');
);
【讨论】:
【参考方案4】:实际上解决这个问题的另一种方法是,用insertRule
覆盖CSS。
它提供了将 CSS 规则注入现有/新样式表的能力。 在我的具体示例中,它看起来像这样:
//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
);
使用我 4 岁的原始示例进行演示: http://jsfiddle.net/raPeX/21/
【讨论】:
【参考方案5】:这类似于 aSeptik 的回答,但是这种方法呢?在 <noscript>
标记中包装您想要使用 JavaScript 禁用的 CSS 代码。这样如果关闭了 javaScript,就会使用 CSS :hover
,否则使用 JavaScript 效果。
例子:
<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>
【讨论】:
【参考方案6】:恐怕没有纯 JavaScript 通用解决方案。 JavaScript 无法自行关闭 CSS :hover
状态。
不过,您可以尝试以下替代解决方法。如果您不介意在 HTML 和 CSS 中稍作修改,则无需通过 JavaScript 手动重置每个 CSS 属性。
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');
)
【讨论】:
我比 noscript 解决方案更喜欢这个解决方案,因为它在 CSS 完全包含在外部文件中时有效,并且在页面加载期间也有效,如果 CSS 先加载但 JS 不加载到后来。如果您在完成加载之前单击内容,使用 jQuery 来“逐步增强”内容通常会导致页面无法正常工作。即使在快速链接上使用快速浏览器,我也经常看到这种情况。 @Mr. Shiny and New:我同意,我也比我的解决方案更喜欢这个!我不知道为什么我以前没有注意到这个的优雅...... “我比 noscript 解决方案更喜欢这个解决方案,因为当 CSS 完全包含在外部文件中时,它可以工作”——<noscript>
解决方案也是如此。您只需将<link>
标签放在<noscript>
中,而不是<style>
标签。我的解决方案确实允许您将所有内容保存在一个样式表文件中,而不是多个文件中。
这不是我想要的,但我认为这个解决方案是最好的妥协!谢谢大家
您也可以使用不同的名称复制相同的样式,并使用 jquery 选择具有该类的所有元素并删除该类并替换为复制类。【参考方案7】:
您可以使用 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);
使属性 !important 并使其成为最后一个 CSS 定义应该覆盖任何以前的定义,除非有更明确的目标。在这种情况下,您可能需要插入更多规则。
【讨论】:
或者您可以将所有 noscript 规则放在一个样式表中,然后从 javascript 禁用样式表。 或者将你的 noscript 样式表<link>
标签放在 <noscript>
元素中?那行得通,对吧?
或者删除“违规”规则:developer.mozilla.org/en/DOM/stylesheet.deleteRule
连IE5都能做到。它的方法以不同的方式调用,但它应该可以工作:msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx。我没有检查其他浏览器,但我猜所有现代浏览器都实现了该标准。
在 Firefox 中我得到 Error: The operation is insecure.
【参考方案8】:
尝试设置链接颜色:
$("ul#mainFilter a").css('color','#000');
编辑:或者更好的是,按照 Christopher 的建议使用 CSS
【讨论】:
jsfiddle.net/raPeX 我做了一个例子。它有效,但这样做有点愚蠢。我将不得不检索每个 CSS 值并将它们添加为样式?一定会有更好的办法。我不想那样做。但 +1 提示 嗨 Meo,不,不,我上面的代码针对的是特定链接,因为这正是我认为你想要的。您可以通过使用a
而不是ul#mainFilter a
来更概括它,如果这是您的意思,或者您是说页面上的每个链接都是不同的颜色?
我已经用 cmets 更新了你的演示,向你展示我的意思:jsfiddle.net/raPeX/2
我已经知道了,谢谢。但问题是,我悬停时不仅颜色发生变化,有时它的背景、边框,有时甚至是行高。这就是为什么我更容易阻止悬停,然后覆盖每一个悬停效果。
这个想法的部分补丁:您可以创建一个 css 规则,选择 a.jsOverride:hover
覆盖所有 css 特征,因此 js 只需将 jsOverride
类添加到所有页面加载时的链接...【参考方案9】:
我会使用 CSS 来防止 :hover 事件改变链接的外观。
a
font:normal 12px/15px arial,verdana,sans-serif;
color:#000;
text-decoration:none;
这个简单的 CSS 意味着链接将始终为黑色且不带下划线。从这个问题中我无法判断外观的变化是否是您想要控制的唯一事情。
【讨论】:
如果 JS 在客户端上不可用,有一个 :hover 效果很好。但如果是我需要覆盖它。我在我的 css 中设置了一个:hover 类,只是想禁用它。 @meo:您不能禁用 CSS 伪类,但可以通过将所有链接样式设置为具有相同的外观/参数来覆盖它。这个答案和我的答案都是这样做的,只是方式不同。以上是关于我可以通过 JavaScript 禁用 CSS :hover 效果吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET MVC 4 Beta 中禁用 Javascript/CSS 缩小
需要帮助使这个简单的 JQuery 图像悬停脚本仅在禁用 javascript 时才弃用为 CSS
如何使用JavaScript禁用CSS转换,更新样式,然后快速恢复转换