我编写了一个适用于桌面和移动设备的jQuery插件。我想知道是否有一种JavaScript方法可以检测设备是否具有触摸屏功能。我正在使用jquery-mobile.js来检测触摸屏事件,并且它在iOS、Android等设备上工作正常,但是我还想编写基于用户设备是否具有触摸屏的条件语句。
这种可能性存在吗?
我编写了一个适用于桌面和移动设备的jQuery插件。我想知道是否有一种JavaScript方法可以检测设备是否具有触摸屏功能。我正在使用jquery-mobile.js来检测触摸屏事件,并且它在iOS、Android等设备上工作正常,但是我还想编写基于用户设备是否具有触摸屏的条件语句。
这种可能性存在吗?
function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch);
if(touchSupport) {
$("html").addClass("ci_touch");
}
else {
$("html").addClass("ci_no_touch");
}
}
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
})();
更多细节在此处。
var isTouchDevice =
(('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
/* Code for touch device /*
}else{
/* Code for non touch device */
}
navigator.MaxTouchPoints
-> navigator.maxTouchPoints
- Jaeho Lee我使用了以上代码的一部分来检测触摸事件,因此我的fancybox iframe只会在台式电脑上出现而不是在触摸设备上出现。但是,当仅使用blmstr的代码时,我发现Android 4.0上的Opera Mini仍然被注册为非触摸设备。(有人知道原因吗?)
最终,我采用了以下代码:
<script>
$(document).ready(function() {
var ua = navigator.userAgent;
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/)
|| ua.match(/BlackBerry/) || ua.match(/Android/)) {
// Touch browser
} else {
// Lightbox code
}
});
</script>
/iPhone|iPod|iPad|Android|BlackBerry/
来进行一次匹配呢? - Dmitry Koroliov实际上,我研究了这个问题并考虑了所有情况。因为这也是我项目中的一个重要问题。所以我找到了以下函数,它适用于所有浏览器的所有版本和所有设备:
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
只返回 boolean
值。
看一下这篇文章,它提供了一个非常好的代码片段,用于在检测到触摸设备时要做什么,或者当触发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();
}
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
这篇文章建议您重新考虑想要检测触摸屏所需的假设,它们可能是错误的。(我为我的应用程序检查了自己的假设,结果发现我的假设确实是错误的!)function isTouchDevice() {
return !!window.ontouchstart;
}
console.log(isTouchDevice());
最后要提到的一个好处是,这段代码不依赖于任何框架和设备。祝使用愉快!
由于混合设备同时使用触摸和鼠标输入,您需要能够动态更改控制代码是否在用户为触摸用户的情况下运行的状态/变量。
触摸设备也会在轻触时触发mousemove
事件。
touchstart
事件被触发后,将其设置为true。在Safari iOS和Chrome for Android上进行测试。
注意:关于MS Surface等的指针事件不确定。
const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;
// `touchstart`, `pointerdown`
const touchHandler = () => {
isUsingTouch = true;
document.addEventListener('mousemove', mousemoveHandler);
};
// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
let time;
return () => {
const now = performance.now();
if (now - time < 20) {
isUsingTouch = false;
document.removeEventListener('mousemove', mousemoveHandler);
}
time = now;
}
})();
// add listeners
if (supportsTouch) {
document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
document.addEventListener('pointerdown', touchHandler);
}