什么是最安全的方式,使用媒体查询,在不使用触摸屏设备时让事情发生?如果没有办法,您是否建议使用 JavaScript 解决方案,例如!window.Touch
Modernizr 或 Modernizr?
11 回答
如今,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 标记中。在这种情况下,touch
您no-touch
可以通过在选择器前加上 .touch 来设置与触摸相关的方面。例如.touch .your-container
。致谢:本·斯威本
截至 2013 年年中,CSS 解决方案似乎并未广泛使用。反而...
Nicholas Zakas 解释说 Modernizr
no-touch
在浏览器不支持触摸时应用了一个 CSS 类。或者用一段简单的代码在 JavaScript 中检测,允许您实现自己的类似 Modernizr 的解决方案:
<script> document.documentElement.className += (("ontouchstart" in document.documentElement) ? ' touch' : ' no-touch'); </script>
然后你可以把你的 CSS 写成:
.no-touch .myClass { ... } .touch .myClass { ... }
实际上有一个媒体查询:
@media (hover: none) { … }
除了 Firefox,它的支持也相当不错。Safari 和 Chrome 是移动设备上最常见的浏览器,它可能就足够了,直到更广泛的采用。
作为标准的一部分,媒体类型不允许您检测触摸功能:
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>
2017 年,来自第二个答案的 CSS 媒体查询仍然无法在 Firefox 上运行。我找到了一个解决方案:-moz-touch-enabled
所以,这里是跨浏览器媒体查询:
@media (-moz-touch-enabled: 1), (pointer:coarse) {
.something {
its: working;
}
}
这将起作用。如果它不让我知道
@media (hover: none) and (pointer: coarse) {
/* Touch screen device style goes here */
}
编辑:不再支持按需悬停
在所有浏览器全球支持 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
该解决方案避免使用现代化器,因为现代化器库是一个非常大的库。如果您要做的只是检测触摸屏,那么当最终编译源的大小是要求时,这将是最好的。
我相信使用 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
使用 JS 或 jQuery 向 body 添加类触摸屏
//allowing mobile only css
var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
if(isMobile){
jQuery("body").attr("class",'touchscreen');
}
我能够使用此解决此问题
@media (hover:none), (hover:on-demand) {
Your class or ID{
attributes
}
}