我编写了一个jQuery插件,可以在桌面和移动设备上使用。我想知道是否有一种方法可以用JavaScript来检测设备是否具有触摸屏功能。我使用jquery-mobile.js来检测触摸屏事件,它适用于iOS, Android等,但我也想根据用户的设备是否有触摸屏来编写条件语句。
这可能吗?
我编写了一个jQuery插件,可以在桌面和移动设备上使用。我想知道是否有一种方法可以用JavaScript来检测设备是否具有触摸屏功能。我使用jquery-mobile.js来检测触摸屏事件,它适用于iOS, Android等,但我也想根据用户的设备是否有触摸屏来编写条件语句。
这可能吗?
当前回答
更新2021
要查看以前的答案,请查看历史记录。我决定从头开始,因为在保存历史的时候,它变得难以控制。
我最初的回答是,使用与Modernizr使用的相同功能可能是一个好主意,但这不再有效,因为他们删除了这个PR: https://github.com/Modernizr/Modernizr/pull/2432上的“touchevents”测试,因为这是一个令人困惑的主题。
话虽如此,这应该是一个相当好的检测浏览器是否具有“触摸功能”的方法:
function isTouchDevice() {
return (('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
}
但是对于比我更聪明的人写过的更高级的用例,我建议阅读这些文章:
斯图·考克斯:你无法检测触摸屏 触摸检测:它是“为什么”,而不是“如何” Patrick H. Lauke的敏感演讲
其他回答
不,不可能。给出的优秀答案永远都是片面的,因为任何给定的方法都会产生假阳性和假阴性。由于操作系统api的原因,甚至浏览器也不总是知道是否存在触摸屏,而且在浏览器会话期间,这一事实可能会发生变化,特别是使用kvm类型的安排。
详见这篇优秀的文章:
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
这篇文章建议你重新考虑那些让你想要检测触摸屏的假设,它们可能是错误的。(我检查了我自己的应用程序,我的假设确实是错误的!)
文章总结道:
对于布局,假设每个人都有触摸屏。鼠标用户可以使用 大型UI控件比触摸用户使用小控件容易得多 的人。悬浮状态也是如此。 对于事件和交互,假设任何人都有触摸屏。 实现键盘、鼠标和触摸交互, 确保互不妨碍。
看看这篇文章,它给出了一个非常好的代码片段,告诉你当检测到触摸设备时该怎么做,或者如果touchstart事件被调用了该怎么做:
$(function(){
if(window.Touch) {
touch_detect.auto_detected();
} else {
document.ontouchstart = touch_detect.surface;
}
}); // End loaded jQuery
var touch_detect = {
auto_detected: function(event){
/* add everything you want to do onLoad here (eg. activating hover controls) */
alert('this was auto detected');
activateTouchArea();
},
surface: function(event){
/* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
alert('this was detected by touching');
activateTouchArea();
}
}; // touch_detect
function activateTouchArea(){
/* make sure our screen doesn't scroll when we move the "touchable area" */
var element = document.getElementById('element_id');
element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
/* modularize preventing the default behavior so we can use it again */
event.preventDefault();
}
我会避免使用屏幕宽度来判断一个设备是否是触控设备。触摸屏比699px大得多,想想Windows 8。Navigatior。userAgent可以很好地覆盖误报。
我建议你在Modernizr上看看这一期。
你是想测试设备是否支持触摸事件,还是一个触摸设备。不幸的是,这不是一回事。
var isTouchScreen = 'createTouch' in document;
or
var isTouchScreen = 'createTouch' in document || screen.width <= 699 ||
ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) ||
ua.match(/Android/);
我想会进行更彻底的检查。
由于Modernizr无法检测Windows Phone 8/WinRT上的IE10,一个简单的跨浏览器解决方案是:
var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
你只需要检查一次,因为设备不会突然支持或不支持触摸,所以只需将它存储在一个变量中,这样你就可以更有效地多次使用它。