144

什么是最安全的方式,使用媒体查询,在不使用触摸屏设备时让事情发生?如果没有办法,您是否建议使用 JavaScript 解决方案,例如!window.TouchModernizr 或 Modernizr?

4

11 回答 11

180
于 2013-01-22T11:31:39.223 回答
60

如今,CSS 媒体查询可用于为具有特定交互功能的设备定义样式,并且也得到广泛支持

例如,悬停可用于测试用户的主要输入机制是否可以悬停在元素上(在没有模拟的支持触摸的设备中这是不正确的)

@media (hover: none) {
  a {
    background: yellow;
  }
}

其他交互式测试有:pointer、any-pointer、hover 和 any-hover

上一个答案

我建议使用modernizr并使用它的媒体查询功能。

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc. and watch `event.streamId`
} else {
   // bind to normal click, mousemove, etc.
}

但是,使用 CSS 时,也有类似的伪类,例如在 Firefox 中。您可以使用:-moz-system-metric(touch-enabled)。但这些功能并非适用于所有浏览器。

对于Apple设备,您可以简单地使用:

if (TouchEvent) {
   //...
}

特别是对于 iPad:

if (Touch) {
    // ...
}

但是,这些不适用于 Android

Modernizr提供了特征检测能力,检测特征是一种很好的编码方式,而不是基于浏览器的编码。

样式化触摸元素

Modernizer 为这个确切的目的将类添加到 HTML 标记中。在这种情况下,touchno-touch可以通过在选择器前加上 .touch 来设置与触摸相关的方面。例如.touch .your-container致谢:本·斯威本

于 2012-07-09T00:31:43.280 回答
56

截至 2013 年年中,CSS 解决方案似乎并未广泛使用。反而...

  1. Nicholas Zakas 解释说 Modernizrno-touch在浏览器不支持触摸时应用了一个 CSS 类。

  2. 或者用一段简单的代码在 JavaScript 中检测,允许您实现自己的类似 Modernizr 的解决方案:

    <script>
        document.documentElement.className += 
        (("ontouchstart" in document.documentElement) ? ' touch' : ' no-touch');
    </script>
    

    然后你可以把你的 CSS 写成:

    .no-touch .myClass {
        ...
    }
    .touch .myClass {
        ...
    }
    
于 2013-08-23T07:44:46.950 回答
42

实际上有一个媒体查询:

@media (hover: none) { … }

除了 Firefox,它的支持也相当不错。Safari 和 Chrome 是移动设备上最常见的浏览器,它可能就足够了,直到更广泛的采用。

于 2018-05-11T04:35:06.617 回答
38

作为标准的一部分,媒体类型不允许您检测触摸功能:

http://www.w3.org/TR/css3-mediaqueries/

因此,没有办法通过 CSS 或媒体查询始终如一地做到这一点,您将不得不求助于 JavaScript。

无需使用 Modernizr,您只需使用纯 JavaScript:

<script type="text/javascript">
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if(is_touch_device) alert("touch is enabled!");
</script>
于 2012-07-09T00:36:41.337 回答
31

2017 年,来自第二个答案的 CSS 媒体查询仍然无法在 Firefox 上运行。我找到了一个解决方案:-moz-touch-enabled


所以,这里是跨浏览器媒体查询:

@media (-moz-touch-enabled: 1), (pointer:coarse) {
    .something {
        its: working;
    }
}
于 2017-05-26T09:00:29.220 回答
14

这将起作用。如果它不让我知道

@media (hover: none) and (pointer: coarse) {
    /* Touch screen device style goes here */
}

编辑:不再支持按需悬停

于 2020-02-01T22:39:50.947 回答
3

在所有浏览器全球支持 CSS4 之前,此解决方案将一直有效。当那一天到来时,只需使用 CSS4。但在那之前,这适用于当前的浏览器。

浏览器-util.js

export const isMobile = {
  android: () => navigator.userAgent.match(/Android/i),
  blackberry: () => navigator.userAgent.match(/BlackBerry/i),
  ios: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
  opera: () => navigator.userAgent.match(/Opera Mini/i),
  windows: () => navigator.userAgent.match(/IEMobile/i),
  any: () => (isMobile.android() || isMobile.blackberry() || 
  isMobile.ios() || isMobile.opera() || isMobile.windows())
};

负载:

老办法:

isMobile.any() ? document.getElementsByTagName("body")[0].className += 'is-touch' : null;

较新的方式:

isMobile.any() ? document.body.classList.add('is-touch') : null;

如果设备有触摸屏,上面的代码会将“is-touch”类添加到 body 标签中。现在,您的 Web 应用程序中的任何位置,您都可以调用 css for :hoverbody:not(.is-touch) the_rest_of_my_css:hover

例如:

button:hover

变成:

body:not(.is-touch) button:hover

该解决方案避免使用现代化器,因为现代化器库是一个非常大的库。如果您要做的只是检测触摸屏,那么当最终编译源的大小是要求时,这将是最好的。

于 2017-04-24T17:36:15.297 回答
2

我相信使用 CSS(2022 年)查询触摸屏的更好方法是使用(pointer:coarse),并且绝对不是使用(hover:none),或组合,正如一些人所建议的那样:(hover: none) and (pointer: coarse),因为(hover:none)不可靠 -有些设备模拟长按(触摸)悬停,所以(hover:none)会不是真的。我在真正的触摸设备(电话,而不是仿真器)上遇到了这样的问题,没有任何其他输入(鼠标或其他东西),“具有”悬停功能,并且我的媒体查询失败。

可能最好的方法是使用 Modernizr,甚至两者都使用(Modernizr 和 CSS,虽然我没有看 Modernizr 做了什么测试,但可能与 CSS 相同:) 像:

.modernizr-touch-class .my-class { // properties }
@media (pointer:coarse) { .my-class { // the same properties } }

但总而言之,这被认为不可靠。当您添加modernizr “触摸事件”测试时,它们会显示有关此问题的简短信息(带有几个链接)。这可能是阅读以找到特定问题的最佳解决方案的好东西,然后对其进行测试......

无论如何,我只是想说这(hover:none)是不可靠的(2022 年)。:D

于 2022-02-01T15:29:01.090 回答
0

使用 JS 或 jQuery 向 body 添加类触摸屏

  //allowing mobile only css
    var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
    if(isMobile){
        jQuery("body").attr("class",'touchscreen');
    }
于 2017-12-08T15:19:21.950 回答
0

我能够使用此解决此问题

@media (hover:none), (hover:on-demand) { 
Your class or ID{
attributes
}    
}
于 2018-10-30T19:35:31.783 回答