使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:15:30  来源:igfitidea点击:

What's the best way to detect a 'touch screen' device using JavaScript?

javascriptjquerytouch

提问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 truein 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 windowwill 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-enabledmedia 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: pointerand hover.

他们在这里使用了非标准的touch-enabled媒体查询功能,我认为这有点奇怪和不好的做法。但是,嘿,在现实世界中,我想它是有效的。将来(当所有人都支持它们时)这些媒体查询功能可以为您提供相同的结果:pointerhover.

Check out the source of how Modernizr are doing it.

查看Modernizr 如何做到这一点来源

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: coarseinstead.

更新(由于评论):上述解决方案是检测“粗指针”(通常是触摸屏)是否是主要输入设备。如果您想检测带有鼠标的设备是否也有触摸屏,您可以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.touchas mentioned earlier.

如果您使用ModernizrModernizr.touch如前所述,它非常易于使用。

However, I prefer using a combination of Modernizr.touchand 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.touchfunction above with ('ontouchstart' in document.documentElement)

如果你不使用 Modernizr,你可以简单地将Modernizr.touch上面的函数替换为('ontouchstart' in document.documentElement)

Also note that testing the user agent iemobilewill give you broader range of detected Microsoft mobile devices than Windows Phone.

另请注意,iemobileWindows Phone.

Also see this SO question

另请参阅此问题

回答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

Working Fiddle

工作小提琴

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
        }
    });
}