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

后端 未结 30 2466
花落未央
花落未央 2020-11-21 23:50

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 capa

相关标签:
30条回答
  • 2020-11-22 00:19

    Have you tried using this function? (This is the same as Modernizr used to use.)

    function is_touch_device() {  
      try {  
        document.createEvent("TouchEvent");  
        return true;  
      } catch (e) {  
        return false;  
      }  
    }
    
    console.log(is_touch_device());

    UPDATE 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.

    Update your function like this to make it work:

    function is_touch_device1() {
      return 'ontouchstart' in window;
    }
    
    console.log(is_touch_device1());

    UPDATE 2

    I found that the above wasn't working on IE10 (returning false on MS Surface). Here is the fix:

    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

    'onmsgesturechange' in window will return true in some IE desktop versions so thats not reliable. This works slightly more reliably:

    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

    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:

    function is_touch_device4() {
        if ("ontouchstart" in window || window.TouchEvent)
            return true;
    
        if (window.DocumentTouch && document instanceof DocumentTouch)
            return true;
    
        const prefixes = ["", "-webkit-", "-moz-", "-o-", "-ms-"];
        const queries = prefixes.map(prefix => `(${prefix}touch-enabled)`);
    
        return window.matchMedia(queries.join(",")).matches;
    }
    
    
    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.

    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.

    0 讨论(0)
  • 2020-11-22 00:19

    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.

    It currently fails on Windows Phone 7 and I haven't been able to find a solution for that browser yet.

    Hope someone finds this useful.

    0 讨论(0)
  • 2020-11-22 00:20
    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/);
    

    would be a more thorough check I suppose.

    0 讨论(0)
  • 2020-11-22 00:21

    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
            }
        });
    }
    
    0 讨论(0)
  • 2020-11-22 00:21

    No, it's not possible. The excellent answers given are only ever partial, because any given method will produce false positives and false negatives. Even the browser doesn't always know if a touchscreen is present, due to OS APIs, and the fact can change during a browser session, particularly with KVM-type arrangements.

    See further details in this excellent article:

    http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

    The article suggests you reconsider the assumptions that make you want to detect touchscreens, they're probably wrong. (I checked my own for my app, and my assumptions were indeed wrong!)

    The article concludes:

    For layouts, assume everyone has a touchscreen. Mouse users can use large UI controls much more easily than touch users can use small ones. The same goes for hover states.

    For events and interactions, assume anyone may have a touchscreen. Implement keyboard, mouse and touch interactions alongside each other, ensuring none block each other.

    0 讨论(0)
  • 2020-11-22 00:21

    It looks like Chrome 24 now support touch events, probably for Windows 8. So the code posted here no longer works. Instead of trying to detect if touch is supported by the browser, I'm now binding both touch and click events and making sure only one is called:

    myCustomBind = function(controlName, callback) {
    
      $(controlName).bind('touchend click', function(e) {
        e.stopPropagation();
        e.preventDefault();
    
        callback.call();
      });
    };
    

    And then calling it:

    myCustomBind('#mnuRealtime', function () { ... });
    

    Hope this helps !

    0 讨论(0)
提交回复
热议问题