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

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

所以,(如何)我可以删除/忽略所有CSS:悬停声明在一次(而不必知道每一个)有他们声明后触摸设备?


当前回答

使用这个:https://jsfiddle.net/57tmy8j3/

如果你感兴趣的原因或其他选择,请继续读下去。

快速删除:使用JS的悬停样式

你可以使用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; }
}

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

最健壮的-通过JS和preend CSS检测触摸:悬停规则

这个方法需要在所有悬停规则前加上body.hasHover。(或您选择的类名)

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

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

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

这应该基本上适用于任何浏览器,并根据需要启用/禁用悬停样式。

这里是完整的例子——modern: https://jsfiddle.net/57tmy8j3/ 遗留(用于旧浏览器):https://jsfiddle.net/dkz17jc5/19/

其他回答

使用带有媒体指针的媒体悬停将帮助您解决此问题。

@media (hover: none) and (pointer: coarse) {
/* Smartphones and touchscreens */

}

使用这个:https://jsfiddle.net/57tmy8j3/

如果你感兴趣的原因或其他选择,请继续读下去。

快速删除:使用JS的悬停样式

你可以使用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; }
}

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

最健壮的-通过JS和preend CSS检测触摸:悬停规则

这个方法需要在所有悬停规则前加上body.hasHover。(或您选择的类名)

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

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

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

这应该基本上适用于任何浏览器,并根据需要启用/禁用悬停样式。

这里是完整的例子——modern: https://jsfiddle.net/57tmy8j3/ 遗留(用于旧浏览器):https://jsfiddle.net/dkz17jc5/19/

2020解决方案- CSS只-没有Javascript

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

@media (hover: hover) and(指针:fine) { A:悬停{颜色:红色;} } <a href="#" >Some Link</a>

你可以使用Modernizr JS(也见这个StackOverflow的答案),或自定义JS函数:

function is_touch_device() {
 return 'ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints;       // works on IE10/11 and Surface
};

if ( is_touch_device() ) {
  $('html').addClass('touch');
} else {
  $('html').addClass('no-touch');
} 

来检测浏览器对touch事件的支持,然后分配一个常规的CSS属性,用html遍历元素。无接触类,像这样:

html.touch a {
    width: 480px;
}

/* FOR THE DESKTOP, SET THE HOVER STATE */
html.no-touch a:hover {
   width: auto;
   color:blue;
   border-color:green;
}

试试这个(我在这个例子中使用background和background-color):

var ClickEventType = ((document.ontouchstart !== null) ? 'click' : 'touchstart');

if (ClickEventType == 'touchstart') {
            $('a').each(function() { // save original..
                var back_color = $(this).css('background-color');
                var background = $(this).css('background');
                $(this).attr('data-back_color', back_color);
                $(this).attr('data-background', background);
            });

            $('a').on('touchend', function(e) { // overwrite with original style..
                var background = $(this).attr('data-background');
                var back_color = $(this).attr('data-back_color');
                if (back_color != undefined) {
                    $(this).css({'background-color': back_color});
                }
                if (background != undefined) {
                    $(this).css({'background': background});
                }
            }).on('touchstart', function(e) { // clear added stlye="" elements..
                $(this).css({'background': '', 'background-color': ''});
            });
}

css:

a {
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}