【问题标题】:CSS Hover style remains after mouse is no longer hovering鼠标不再悬停后 CSS 悬停样式仍然存在
【发布时间】:2014-02-22 18:05:18
【问题描述】:

在 Safari 版本 7.0.1 和 IE8 中会发生以下情况。

重现问题的步骤: http://goo.gl/lP3Ky1

问题: 关闭弹出菜单后,该行的悬停状态保持不变,无论鼠标在哪里,它都不会消失,直到您再次悬停在它上面。

预期的行为是什么? 关闭弹出菜单后,该行的悬停状态应该消失。

有人知道 Safari 7.0.1 和 IE8 的修复方法吗?我可以通过一些手动方式“取消触发”css 悬停状态。

【问题讨论】:

  • Safari 6.1也存在这个bug,但据我所知,开发工具显示悬停状态就好了。
  • @Marcel 这不是浏览器错误
  • 在尝试了很多解决方法后,我在 safari 上遇到了类似的问题,我最终使用了“mouseover”和“mouseout”事件并从我的 css 中删除了 :hover 伪选择器。

标签: css internet-explorer-8 safari hover


【解决方案1】:

这是一个需要解决的有趣问题。虽然解决方案有点老套,但它确实有效。将 HTML 设置为“boo”后,我们克隆整行,插入它,然后删除旧行:

$(function() {
  $("table").on("click", "td", function() {
    $("#menu")
        .clone()
        .one("click", function() {
              var $td = $(this).closest("td"),
                  $tr = $td.parent();

              $td.html("boo");
              $tr.clone(/* true */).insertAfter($tr);
              $tr.remove();
              return false;
        })
        .appendTo(this)
        .show();
  });
});

http://jsfiddle.net/ryanwheale/3BUaT/26/

【讨论】:

  • 因此“错误的方法”不会变得更正确! ;-)
  • 当错误的方法是你唯一的方法时,它会变得不那么错误;)当菜单消失时,浏览器没有注册 mouseout 事件。我什至尝试将菜单设置为动画左侧,以强制鼠标越过边界……但无济于事。
  • “如果错误的方法是你唯一的方法......”那么你的设计就有问题! ;-) 而且我认为我在回答中表明这不是“唯一的方法”。所以没有理由“做错事”!
【解决方案2】:

这是一种解决方法 - http://jsfiddle.net/3BUaT/11/。在浏览了许多 stackoverflow 帖子后,了解到无法从 javascript 中删除 css 伪类。因此,绝对有必要进行解决。

我正在使用

tr.hovered td {
  background-color: lightblue;
}

而不是常规的 CSS 悬停状态。

问题是,当您单击菜单中的 li 时,它并没有完全从 safari 中的 CSS 触发 mouseout 事件。从技术上讲,您实际上并没有将鼠标移出元素。只是元素被删除了。这似乎是 Safari 中的一个错误。

【讨论】:

  • 这是一个可靠的 JavaScript 解决方案。但我不想强迫正常运行的浏览器使用 javascript 完成悬停样式,而是坚持使用 css 的 :hover。
  • @Marcel:这听起来有点好笑,因为整个菜单都依赖于 Javascript!无论这些浏览器中是否存在错误,它至少是“不好的做法”(通过脚本将绝对定位元素添加到表格单元格中,该表格单元格也位于单元格“外部”,然后再次删除它们)。我也不明白为什么悬停伪类属于表格行(而不是单元格)!?另外看看如果用户点击几个单元格会发生什么(每次点击都会添加一个菜单,但它们都没有“消失”,所以它们都重叠)。你的整个方法并不理想。
  • @Marcel:因此,如果您希望在禁用 JS 的情况下通过 CSS 实现悬停效果,请在您的 HTML 元素中使用 no-js 类,例如 Modernizr 即可。如果 JS 可用,就使用建议的 JS 解决方案!
【解决方案3】:

这不是浏览器的错。是你的。您正在将菜单列表附加到该行。所以菜单列表是该行的子项。因此,如果您将鼠标悬停在子节点上,则父节点也将处于悬停状态。

我已经更新了你的 jsfiddle:

Jsfiddle;

$(function() {
  $("td").on("click", function() {
    $("#menu")
        .clone()
        .one("click", function() {
          // this is key to reproduce it.
          $(this).closest("td").html("boo");
          return false;
        })
        .appendTo($(this).parent().parent().last())
        .show();
  });
});

【讨论】:

    【解决方案4】:

    您正在使用您的函数将 div #menu 附加到 td。现在,当您将鼠标悬停在 td 或附加菜单上时,CSS 会将悬停状态应用于 td。将鼠标悬停在菜单上会应用 tr:hover td css,因为菜单现在是 td 的一部分。

    【讨论】:

    • 这可能是真的。但我正在寻找修复或解决方法,以使这项工作在 safari 和 IE8 中完全有效。它适用于所有其他浏览器。我可以通过一些手动方式“取消触发”css悬停状态......
    【解决方案5】:

    好的,这是我提出的解决方案,它考虑了我的 cmets(根据 Tejas Jayasheel 的回答)的观点:JSFiddle

    区别在于:

    • #menu 没有被克隆也没有添加到表格单元格中,而是只是重新定位(因此该元素也只显示一次)
    • 仅当 HTML 元素中存在“no-js”类时才应用 CSS 悬停(需要在原始文件中添加)
    • 否则悬停效果是通过将“clicked”类应用于单元格来实现的
    • 此外,当菜单已经可见时,通过在所有 TD 上切换另一个类来“禁用”悬停效果
    • 在菜单外点击已“点击”的单元格将关闭/隐藏菜单,无需任何进一步操作

      .no-js td:hover,
      td.hover-enabled:hover,
      td.clicked { background-color: lightblue; }

    预期的行为是什么?关闭弹出菜单后,该行的悬停状态应该消失。

    也许……!但是请记住,通过从 DOM 中删除悬停的元素,您会严重“混淆”浏览器。我猜 Safari 和 IE 8 只是“不承认”以前悬停的部分不再悬停。这可能是也可能不是“错误”。但至少这是“不好的做法/写作风格”,应该避免!

    有人知道 Safari 版本 7.0.1 和 IE8 的修复方法吗?我可以通过一些手动方式“取消触发”css悬停状态。

    我的示例中显示了“修复”。在编写脚本和悬停时,通常建议添加、删除或切换类。通过这样做,您可以完全避免“问题”。因为即使在任何浏览器的未来版本中,这种情况下的行为充其量也是“不可预测的”。

    【讨论】:

      猜你喜欢
      • 2016-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2011-08-04
      • 2018-09-03
      • 2010-10-11
      相关资源
      最近更新 更多