媒体查询以检测设备是否为触摸屏


Answers:


37

我建议使用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(window.TouchEvent) {
   //.....
}

特别是对于Ipad:

if(window.Touch) {
    //....
}

但是,这些在Android上不起作用

Modernizr提供了功能检测功能,并且检测功能是一种很好的编码方式,而不是基于浏览器进行编码。

样式触摸元素

为此,Modernizer将类添加到HTML标记中。在这种情况下,touch并且no-touch使您可以通过.touch前缀您选择风格你触摸相关的方面。例如.touch .your-container鸣谢:Ben Swinburne


我是否认为没有psedo类可用于所有现代设备/浏览器?
JJJollyjim'7

@ JJ56,是的,不是每个浏览器都支持touch伪类。但这就是modernizr完美的地方:)
Starx

18
Modernizr.touch测试仅指示浏览器是否支持触摸事件,这不一定反映触摸屏设备。例如,Palm Pre / WebOS(触摸)电话不支持触摸事件,因此无法通过此测试。
numediaweb

5
补充一点,如果您仍然要包括现代化的话;为此,Modernizer将类添加到body标签。在这种情况下,touchno-touch让您可以风格你触摸用前缀您选择相关的方面.touch。例如.touch .your-container
Ben Swinburne 2013年

2
对我来说,modernizr似乎将touch类添加到html标签,而不是body标签。
罗宾·考克斯

162

实际上,CSS4媒体查询草稿中有一个属性。

“指针”媒体功能用于查询指针设备(例如鼠标)的存在和准确性。如果设备具有多种输入机制,则建议UA报告主要输入机制中功能最弱的定点设备的特征。该媒体查询采用以下值:

'none'-
设备的输入机制不包括定点设备。

“粗略”
-设备的输入机制包括精度有限的定点设备。

'精细'
-设备的输入机制包括一个精确的指点设备。

可以这样使用:

/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
@media (pointer:coarse) {
    input[type="checkbox"], input[type="radio"] {
        min-width:30px;
        min-height:40px;
        background:transparent;
    }
}

我还在Chromium项目中找到与此有关的票证

浏览器兼容性可以在以下位置进行测试 Quirksmode下。这些是我的结果(2013年1月22日):

  • Chrome / Win:有效
  • Chrome / iOS:不起作用
  • Safari / iOS6:不起作用

3
当提供的解决方案即使根据发布者也无法使用时,如何最大程度地回答这个问题?
erdomester

5
浏览器对此的支持不再那么糟糕:Edge,Chrome,Safari,iOS和Android。参见:caniuse.com/#feat=css-media-interaction
Josa


为我工作;)感谢您对此进行研究!
Verri

51

截至2013年中,CSS解决方案似乎尚未广泛使用。代替...

  1. Nicholas Zakas解释说no-touch当浏览器不支持触摸时,Modernizr将应用CSS类。

  2. 或使用一段简单的代码在JavaScript中进行检测,从而使您能够实现自己的类似Modernizr的解决方案:

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

    然后,您可以将CSS编写为:

    .no-touch .myClass {
        ...
    }
    .touch .myClass {
        ...
    }

第二个很好。为我创造魅力!谢谢。
Garavani 2014年

@ bjb568感谢您提出的修改建议,这是一种更现代的选择,但是由于它仅在IE 10及更高版本中有效,因此我认为最好暂时保留此版本。
西蒙·伊斯特

听起来该类将在html标签上;这意味着使用CSP时默认情况下禁用它。
狮子座

35

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

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>

AFAIK和window.touch&& window.TouchEvent仅适用于Apple设备。
Starx 2012年

22
@vsync Modernizr是一种将所有对开发人员有用的测试放在一个托管库中的好方法,因为他们不必在每次需要测试特定功能(例如触摸事件和必须找到此页面)时都必须使用Google。仅供参考,您可以使用所需的测试来自定义一个自定义的Modernizr构建。这是一种在项目之间始终以相同方式测试功能的好方法,您可以使用JS语法(即Modernizr.touch)或CSS类(.touch .my-element {})。我认为这是对人类智慧的侮辱,因为他们没有意识到我们可以做事而不必每次都重新发明轮子。
AlejandroGarcíaIglesias

11
好吧,我从事过数百个项目,而我从来不需要这样的东西,在大多数情况下,您只需要进行很少的测试即可,在大多数情况下,我说的测试次数不得超过5个,因此这5个代码,然后直接将它们放在您的代码中,而无需实际访问Modernizer网站,进行自定义构建,将其包含在您的页面中,等等。开发人员不应该那么懒。Web开发人员应始终具有“如何使代码更轻便?”的思想。恕我直言和多年的经验。如今的开发人员似乎喜欢包含大量脚本:/
vsync

2
有人说懒。我说为什么要重新发明轮子?当出现新设备/版本/平台并且您的特殊情况需要更改时该怎么办?您是(a)尝试自己设计出特殊情况检测代码,然后移植回自定义代码,在此过程中重新熟悉该代码,还是b)下载更新版本的Modernizr并放入其中?我知道该怎么办。+1到GarciaWebDev。
Sc0ttyD

@ Sc0ttyD我个人的喜好是最初学习编码的东西,而无需依赖诸如Modernizr之类的库。有朝一日,您可能需要由那个人为新设备编写代码,并且不想被困住,因为没有库就无法做到。更不用说,可能有很多人只是没有时间去学习新图书馆。
Alex W

28

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


因此,这是跨浏览器的媒体查询:

@media (-moz-touch-enabled: 1), (pointer:coarse) {
    .something {
        its: working;
    }
}

这应该是更高的答案。firefox正在努力实施该规范,因此-moz-touch-enabled将不再需要
-Dogoku


@ user3445853 OP询问如何(通过媒体查询)使用触摸屏检测设备。如果规则“(pointer:none)”为真,则表示该设备肯定没有触摸屏。但是有人要确认我的意见(或无):)
索科洛夫

-moz-touch-enabledFirefox 58+可能不支持。同样,此解决方案不涵盖Firefox 58-63(因为Firefox 64+支持指针查询)。来源:developer.mozilla.org/en-US/docs/Web/CSS/@media/…–
fgblomqvist

24

实际上有一个媒体查询:

@media (hover: none) {  }

除了Firefox之外,它还受到很好的支持。Safari和Chrome是移动设备上最常见的浏览器,它可能需要足够的使用才能被广泛采用。


2
…并且在接下来的几周内,FF也将提供支持。
retrovertigo

5

这将起作用。如果没有让我知道

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

编辑:不再支持按需悬停


3

在所有浏览器都全局支持CSS4之前,此解决方案将一直有效。当那一天到来时,请使用CSS4。但是直到那时,这对于当前的浏览器仍然有效。

browser-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用于:hover的任何位置都可以调用body:not(.is-touch) the_rest_of_my_css:hover

例如:

button:hover

变成:

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

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


0

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

  //allowing mobile only css
    var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
    if(isMobile){
        jQuery("body").attr("class",'touchscreen');
    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.