使用 JavaScript 检测“触摸屏”设备的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4817029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the best way to detect a 'touch screen' device using JavaScript?
提问by screenm0nkey
I've written a jQuery plug-in that's for use on both desktop and mobile devices. I wondered if there is a way with JavaScript to detect if the device has touch screen capability. I'm using jquery-mobile.js to detect the touch screen events and it works on iOS, Android etc., but I'd also like to write conditional statements based on whether the user's device has a touch screen.
我编写了一个可在桌面和移动设备上使用的 jQuery 插件。我想知道是否有一种方法可以使用 JavaScript 来检测设备是否具有触摸屏功能。我正在使用 jquery-mobile.js 来检测触摸屏事件,它适用于 iOS、Android 等,但我还想根据用户的设备是否有触摸屏来编写条件语句。
Is that possible?
那可能吗?
采纳答案by Alan Christopher Thomas
Update: Please read blmstr's answerbelow before pulling a whole feature detection library into your project. Detecting actual touch support is more complex, and Modernizr only covers a basic use case.
更新:在将整个特征检测库拉入您的项目之前,请阅读下面的blmstr 答案。检测实际触摸支持更为复杂,Modernizr 仅涵盖基本用例。
Modernizris a great, lightweight way to do all kinds of feature detection on any site.
Modernizr是一种很棒的轻量级方法,可以在任何站点上进行各种特征检测。
It simply adds classes to the html element for each feature.
它只是为每个功能的 html 元素添加类。
You can then target those features easily in CSS and JS. For example:
然后,您可以在 CSS 和 JS 中轻松定位这些功能。例如:
html.touch div {
width: 480px;
}
html.no-touch div {
width: auto;
}
And Javascript (jQuery example):
和 Javascript(jQuery 示例):
$('html.touch #popup').hide();
回答by bolmaster2
Have you tried using this function? (This is the same as Modernizr used to use.)
你试过使用这个功能吗?(这与 Modernizr 过去使用的相同。)
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
console.log(is_touch_device());
UPDATE 1
更新 1
document.createEvent("TouchEvent")
have started to return true
in the latest chrome (v. 17). Modernizr updated this a while ago. Check Modernizr test out here.
document.createEvent("TouchEvent")
已经开始true
在最新的 chrome (v. 17) 中返回。Modernizr 不久前更新了这个。在这里检查 Modernizr 测试。
Update your function like this to make it work:
像这样更新您的函数以使其工作:
function is_touch_device1() {
return 'ontouchstart' in window;
}
console.log(is_touch_device1());
UPDATE 2
更新 2
I found that the above wasn't working on IE10 (returning false on MS Surface). Here is the fix:
我发现上述内容不适用于 IE10(在 MS Surface 上返回 false)。这是修复:
function is_touch_device2() {
return 'ontouchstart' in window // works on most browsers
|| 'onmsgesturechange' in window; // works on IE10 with some false positives
};
console.log(is_touch_device2());
UPDATE 3
更新 3
'onmsgesturechange' in window
will return true in some IE desktop versions so thats not reliable. This works slightly more reliably:
'onmsgesturechange' in window
在某些 IE 桌面版本中将返回 true,因此不可靠。这稍微更可靠地工作:
function is_touch_device3() {
return !!('ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints); // works on IE10/11 and Surface
};
console.log(is_touch_device3());
UPDATE 2018
2018 年更新
Time goes by and there are new and better ways to test this. I've basically extracted and simplified Modernizr's way of checking it:
随着时间的流逝,有新的更好的方法来测试这一点。我基本上提取并简化了 Modernizr 的检查方式:
function is_touch_device4() {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
}
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
}
console.log(is_touch_device4());
Here they are using the non-standard touch-enabled
media query feature, which I think is kinda weird and bad practice. But hey, in the real world I guess it works. In the future (when they are supported by all) those media query features could give you the same results: pointer
and hover
.
他们在这里使用了非标准的touch-enabled
媒体查询功能,我认为这有点奇怪和不好的做法。但是,嘿,在现实世界中,我想它是有效的。将来(当所有人都支持它们时)这些媒体查询功能可以为您提供相同的结果:pointer
和hover
.
Check out the source of how Modernizr are doing it.
For a good article that explains the issues with touch detection, see: Stu Cox: You Can't Detect a Touchscreen.
有关解释触摸检测问题的好文章,请参阅: Stu Cox:您无法检测到触摸屏。
回答by Matt Stow
As Modernizr doesn't detect IE10 on Windows Phone 8/WinRT, a simple, cross-browser solution is:
由于 Modernizr 在 Windows Phone 8/WinRT 上没有检测到 IE10,一个简单的跨浏览器解决方案是:
var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
You only ever need to check once as the device won't suddenly support or not support touch, so just store it in a variable so you can use it multiple times more efficiently.
您只需要检查一次,因为设备不会突然支持或不支持触摸,所以只需将其存储在一个变量中,这样您就可以更有效地多次使用它。
回答by David
Using all the comments above I've assembled the following code that is working for my needs:
使用上面的所有评论,我组装了以下代码,以满足我的需要:
var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
I have tested this on iPad, Android (Browser and Chrome), Blackberry Playbook, iPhone 4s, Windows Phone 8, IE 10, IE 8, IE 10 (Windows 8 with Touchscreen), Opera, Chrome and Firefox.
我已经在 iPad、Android(浏览器和 Chrome)、Blackberry Playbook、iPhone 4s、Windows Phone 8、IE 10、IE 8、IE 10(带触摸屏的 Windows 8)、Opera、Chrome 和 Firefox 上对此进行了测试。
It currently fails on Windows Phone 7 and I haven't been able to find a solution for that browser yet.
它目前在 Windows Phone 7 上失败,我还没有找到适用于该浏览器的解决方案。
Hope someone finds this useful.
希望有人觉得这很有用。
回答by Blackbam
Since the introduction of interaction media featuresyou simply can do:
由于引入了交互媒体功能,您可以简单地执行以下操作:
if(window.matchMedia("(pointer: coarse)").matches) {
// touchscreen
}
https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer
https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer
Update (due to comments): The above solution is to detect if a "coarse pointer" - usually a touch screen - is the primary input device. In case you want to dectect if a device with e.g. a mouse also has a touch screen you may use any-pointer: coarse
instead.
更新(由于评论):上述解决方案是检测“粗指针”(通常是触摸屏)是否是主要输入设备。如果您想检测带有鼠标的设备是否也有触摸屏,您可以any-pointer: coarse
改用。
For more information have a look here: Detecting that the browser has no mouse and is touch-only
有关更多信息,请查看此处:检测浏览器没有鼠标并且仅触摸
回答by Benny Neugebauer
I like this one:
我喜欢这个:
function isTouchDevice(){
return typeof window.ontouchstart !== 'undefined';
}
alert(isTouchDevice());
回答by Peter-Pan
If you use Modernizr, it is very easy to use Modernizr.touch
as mentioned earlier.
如果您使用Modernizr,Modernizr.touch
如前所述,它非常易于使用。
However, I prefer using a combination of Modernizr.touch
and user agent testing, just to be safe.
但是,Modernizr.touch
为了安全起见,我更喜欢结合使用和用户代理测试。
var deviceAgent = navigator.userAgent.toLowerCase();
var isTouchDevice = Modernizr.touch ||
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/) ||
deviceAgent.match(/(iemobile)/) ||
deviceAgent.match(/iphone/i) ||
deviceAgent.match(/ipad/i) ||
deviceAgent.match(/ipod/i) ||
deviceAgent.match(/blackberry/i) ||
deviceAgent.match(/bada/i));
if (isTouchDevice) {
//Do something touchy
} else {
//Can't touch this
}
If you don't use Modernizr, you can simply replace the Modernizr.touch
function above with ('ontouchstart' in document.documentElement)
如果你不使用 Modernizr,你可以简单地将Modernizr.touch
上面的函数替换为('ontouchstart' in document.documentElement)
Also note that testing the user agent iemobile
will give you broader range of detected Microsoft mobile devices than Windows Phone
.
另请注意,iemobile
与Windows Phone
.
回答by Martin Lantzsch
We tried the modernizr implementation, but detecting the touch events is not consistent anymore (IE 10 has touch events on windows desktop, IE 11 works, because the've dropped touch events and added pointer api).
我们尝试了 Modernizr 实现,但检测触摸事件不再一致(IE 10 在 Windows 桌面上有触摸事件,IE 11 可以工作,因为已经删除了触摸事件并添加了指针 api)。
So we decided to optimize the website as a touch site as long as we don't know what input type the user has. This is more reliable than any other solution.
所以我们决定将网站优化为触摸网站,只要我们不知道用户有什么输入类型。这比任何其他解决方案都更可靠。
Our researches say, that most desktop users move with their mouse over the screen before they click, so we can detect them and change the behaviour before they are able to click or hover anything.
我们的研究表明,大多数桌面用户在点击之前会用鼠标在屏幕上移动,因此我们可以检测到他们并在他们能够点击或悬停任何东西之前改变行为。
This is a simplified version of our code:
这是我们代码的简化版本:
var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
isTouch = false;
window.removeEventListener('mousemove', mouseMoveDetector);
});
回答by Aamir Shahzad
I have achieved it like this;
我是这样实现的;
function isTouchDevice(){
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
if(isTouchDevice()===true) {
alert('Touch Device'); //your logic for touch device
}
else {
alert('Not a Touch Device'); //your logic for non touch device
}
回答by Ivan Castellanos
There is something better than checking if they have a touchScreen, is to check if they are using it, plus that's easier to check.
有什么比检查他们是否有触摸屏更好的方法是检查他们是否正在使用它,而且这更容易检查。
if (window.addEventListener) {
var once = false;
window.addEventListener('touchstart', function(){
if (!once) {
once = true;
// Do what you need for touch-screens only
}
});
}