我编写了一个jQuery插件,可以在桌面和移动设备上使用。我想知道是否有一种方法可以用JavaScript来检测设备是否具有触摸屏功能。我使用jquery-mobile.js来检测触摸屏事件,它适用于iOS, Android等,但我也想根据用户的设备是否有触摸屏来编写条件语句。
这可能吗?
我编写了一个jQuery插件,可以在桌面和移动设备上使用。我想知道是否有一种方法可以用JavaScript来检测设备是否具有触摸屏功能。我使用jquery-mobile.js来检测触摸屏事件,它适用于iOS, Android等,但我也想根据用户的设备是否有触摸屏来编写条件语句。
这可能吗?
当前回答
事实上,我研究了这个问题并考虑了各种情况。因为这在我的项目中也是一个大问题。所以我达到了下面的功能,它适用于所有设备上所有浏览器的所有版本:
const isTouchDevice = () => {
const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
const mq = query => window.matchMedia(query).matches;
if (
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof DocumentTouch)
) {
return true;
}
return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};
提示:显然,isTouchDevice只返回布尔值。
其他回答
试图检测触控的最大“陷阱”是同时支持触控和触控板/鼠标的混合设备。即使你能够正确地检测用户的设备是否支持触摸,你真正需要做的是检测用户当前使用的输入设备。这里有一份关于这个挑战的详细报告和可能的解决方案。
基本上,判断用户是触摸屏幕还是使用鼠标/触控板的方法是在页面上注册touchstart和mouseover事件:
document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"
触摸动作会触发这两个事件,尽管前者(touchstart)在大多数设备上总是先触发。因此,依靠这个可预测的事件序列,您可以创建一种机制,动态地向文档根添加或删除一个can-touch类,以反映当前用户在文档上的输入类型:
;(function(){
var isTouch = false //var to indicate current input type (is touch versus no touch)
var isTouchTimer
var curRootClass = '' //var indicating current document root class ("can-touch" or "")
function addtouchclass(e){
clearTimeout(isTouchTimer)
isTouch = true
if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
curRootClass = 'can-touch'
document.documentElement.classList.add(curRootClass)
}
isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
}
function removetouchclass(e){
if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
isTouch = false
curRootClass = ''
document.documentElement.classList.remove('can-touch')
}
}
document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();
详情请点击这里。
到目前为止,这似乎对我来说很有效:
//Checks if a touch screen
is_touch_screen = 'ontouchstart' in document.documentElement;
if (is_touch_screen) {
// Do something if a touch screen
}
else {
// Not a touch screen (i.e. desktop)
}
有一种方法比检查他们是否拥有触摸屏更好,那就是检查他们是否正在使用触摸屏,而且这更容易检查。
if (window.addEventListener) {
var once = false;
window.addEventListener('touchstart', function(){
if (!once) {
once = true;
// Do what you need for touch-screens only
}
});
}
更新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的敏感演讲
由于引入了交互媒体功能,你可以简单地做到:
if(window.matchMedia("(pointer: coarse)").matches) {
// touchscreen
}
https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer
更新(由于评论):上面的解决方案是检测“粗指针”——通常是触摸屏——是否是主要输入设备。如果你想检测一个带有鼠标的设备是否也有触摸屏,你可以使用任意指针:粗。
有关更多信息,请查看这里:检测浏览器没有鼠标,只能触摸