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

screenm0nkey picture screenm0nkey · Jan 27, 2011 · Viewed 397k times · Source

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.

Is that possible?

Answer

bolmaster2 picture bolmaster2 · Jan 27, 2011

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.