我可以通过 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 中设置了 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/)。我正在寻找一个通用的解决方案。

有人知道怎么做吗?

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() 函数。这是一个示例,当您单击列表项时,它不会再悬停:

例如:

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

【讨论】:

【参考方案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 的回答,但是这种方法呢?在 &lt;noscript&gt; 标记中包装您想要使用 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 完全包含在外部文件中时,它可以工作”——&lt;noscript&gt; 解决方案也是如此。您只需将&lt;link&gt; 标签放在&lt;noscript&gt; 中,而不是&lt;style&gt; 标签。我的解决方案确实允许您将所有内容保存在一个样式表文件中,而不是多个文件中。 这不是我想要的,但我认为这个解决方案是最好的妥协!谢谢大家 您也可以使用不同的名称复制相同的样式,并使用 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 样式表 &lt;link&gt; 标签放在 &lt;noscript&gt; 元素中?那行得通,对吧? 或者删除“违规”规则: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 效果吗?的主要内容,如果未能解决你的问题,请参考以下文章

通过 CSS 禁用自动完成

如何在 ASP.NET MVC 4 Beta 中禁用 Javascript/CSS 缩小

需要帮助使这个简单的 JQuery 图像悬停脚本仅在禁用 javascript 时才弃用为 CSS

如何使用JavaScript禁用CSS转换,更新样式,然后快速恢复转换

在 JavaScript 中更改 HTML 元素的样式并暂时禁用其 CSS 转换无法可靠运行 [重复]

通过javascript每次点击动态禁用文本选择?