如何删除/忽略触摸设备上的悬停 css 样式

新手上路,请多包涵

如果用户通过触摸设备访问我们的网站,我想忽略所有 :hover CSS 声明。因为 :hover CSS 没有意义,如果平板电脑在点击/点击时触发它,它甚至可能会令人不安,因为它可能会一直坚持到元素失去焦点。老实说,我不知道为什么触摸设备首先需要触发 :hover 但这是现实,所以这个问题也是现实。

 a:hover {
  color:blue;
  border-color:green;
  /* etc. > ignore all at once for touch devices */
}

那么,(如何)我可以删除/忽略触摸设备的所有 CSS :hover 声明后立即(不必知道每一个)声明?

原文由 Simon Ferndriger 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 853
2 个回答

2020 解决方案 - 仅 CSS - 无 Javascript

使用带有 媒体指针媒体悬停 将帮助您解决此问题。在 chrome Web 和 android mobile 上测试。我知道这个老问题,但我没有找到这样的解决方案。

 @media (hover: hover) and (pointer: fine) {
  a:hover { color: red; }
}
 <a href="#" >Some Link</a>

原文由 Hải Bùi 发布,翻译遵循 CC BY-SA 4.0 许可协议

tl;博士使用这个: https ://jsfiddle.net/57tmy8j3/

如果您对原因或其他选项感兴趣,请继续阅读。

Quick’n’dirty - 使用 JS 删除 :hover 样式

您可以使用 Javascript 删除所有包含 :hover 的 CSS 规则。这样做的好处是不必接触 CSS,甚至可以与旧浏览器兼容。

 function hasTouch() {
  return 'ontouchstart' in document.documentElement
         || navigator.maxTouchPoints > 0
         || navigator.msMaxTouchPoints > 0;
}

if (hasTouch()) { // remove all the :hover stylesheets
  try { // prevent exception on browsers not supporting DOM styleSheets properly
    for (var si in document.styleSheets) {
      var styleSheet = document.styleSheets[si];
      if (!styleSheet.rules) continue;

      for (var ri = styleSheet.rules.length - 1; ri >= 0; ri--) {
        if (!styleSheet.rules[ri].selectorText) continue;

        if (styleSheet.rules[ri].selectorText.match(':hover')) {
          styleSheet.deleteRule(ri);
        }
      }
    }
  } catch (ex) {}
}

局限性:样式表必须托管在 同一个域中(这意味着没有 CDN)。禁用 鼠标和触摸混合设备(如 Surface 或 iPad Pro)上的悬停,这会损害用户体验。

仅限 CSS - 使用媒体查询

将所有 :hover 规则放在 @media 块中:

 @media (hover: hover) {
  a:hover { color: blue; }
}

或者,覆盖所有悬停规则(与旧浏览器兼容):

 a:hover { color: blue; }

@media (hover: none) {
  a:hover { color: inherit; }
}

限制:使用 WebView 时仅适用于 iOS 9.0+、Android 版 Chrome 或 Android 5.0+。 hover: hover 打破旧浏览器上的悬停效果, hover: none 需要覆盖所有先前定义的 CSS 规则。两者都 与混合鼠标和触摸设备不兼容

最强大的 - 通过 JS 检测触摸并预先添加 CSS :hover 规则

此方法需要在所有悬停规则前加上 body.hasHover 。 (或您选择的班级名称)

 body.hasHover a:hover { color: blue; }

可以使用第一个示例中的 hasTouch() 添加 hasHover 类:

 if (!hasTouch()) document.body.className += ' hasHover'

然而,这与前面的例子一样,对于混合触摸设备也有同样的缺点,这给我们带来了最终的解决方案。每当鼠标光标移动时启用悬停效果,每当检测到触摸时禁用悬停效果。

 function watchForHover() {
  // lastTouchTime is used for ignoring emulated mousemove events
  let lastTouchTime = 0

  function enableHover() {
    if (new Date() - lastTouchTime < 500) return
    document.body.classList.add('hasHover')
  }

  function disableHover() {
    document.body.classList.remove('hasHover')
  }

  function updateLastTouchTime() {
    lastTouchTime = new Date()
  }

  document.addEventListener('touchstart', updateLastTouchTime, true)
  document.addEventListener('touchstart', disableHover, true)
  document.addEventListener('mousemove', enableHover, true)

  enableHover()
}

watchForHover()

这基本上可以在任何浏览器中工作,并根据需要启用/禁用悬停样式。

这是完整的示例 - 现代: https ://jsfiddle.net/57tmy8j3/

旧版(用于旧浏览器): https ://jsfiddle.net/dkz17jc5/19/

原文由 blade 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏