What's the Best Way to Detect a 'Touch Screen' Device Using JavaScript

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

Update: Please read blmstr's answer below 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.

Modernizr is a great, lightweight way to do all kinds of feature detection on any site.

It simply adds classes to the html element for each feature.

You can then target those features easily in CSS and JS. For example:

html.touch div {
width: 480px;
}

html.no-touch div {
width: auto;
}

And Javascript (jQuery example):

$('html.touch #popup').hide();

How detecting if the browser has touch capabilities ?

To answer the question exactly as set, if you put this function into your Javascript code you can just run it and set a flag which you can use in your code afterwards if you want to do things differently for a touchscreen.

function isTouchDevice() {
return (('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
}

const myFlag = isTouchDevice();

....
// example
if (myFlag) { alert('You can move the object with your finger'); }
else { alert('Use the arrow keys on your keyboard to move the object'); }

But remember a user may use the device as a touchscreen one minute and as a keyboard device the next. You can code for sensing both key and touch events and unless your site absolutely needs the user to use a touch device you can accommodate both methods of input.

How to detect touch device in 2019?

This is really simple with just one line of code:

const touch = matchMedia('(hover: none)').matches;

- What? matchMedia?

- This is just a JS API to do CSS @media queries. And it is supported in modern browsers: https://caniuse.com/#feat=matchmedia. Of course, you may use such queries directly in CSS:

@media (hover: none){
/* touch stuff goes here */
}

- Ok, what @media queries may be also useful?

@media (hover: none) and (pointer: coarse) {
/* touchscreens */
}
@media (hover: none) and (pointer: fine) {
/* stylus */
}
@media (hover: hover) and (pointer: coarse) {
/* controllers */
}
@media (hover: hover) and (pointer: fine) {
/* mouse or touchpad */
}

But this will query only the primary input method. If you want to go deeper, you may use any-hover and any-pointer to query all input devices.

UPD: hack for old browsers removed, seems like most old browsers does not support hover and pointer media queries too. You may use touch event detection and touch-only navigator properties from another answers

UPD2: In your case, it's preferable to use

const touch = matchMedia('(hover: none), (pointer: coarse)').matches;

Detecting touch screen devices with Javascript

+1 for doing hover and click both. One other way could be using CSS media queries and using some styles only for smaller screens / mobile devices, which are the ones most likely to have touch / tap functionality. So if you have some specific styles via CSS, and from jQuery you check those elements for the mobile device style properties you could hook into them to write you mobile specific code.

See here: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Detect click vs. touch in JavaScript

You can use the pointerType property on PointerEvent to detect the input type ("mouse", "touch", or "pen"):

element.addEventListener('pointerdown', (event) => {
if (event.pointerType === "mouse") {}
if (event.pointerType === "touch") {}
if (event.pointerType === "pen") {}
});

If you want specific events for each type of click, you can create custom events:

const mouse = new Event("mouseclick");
const touch = new Event("touch");
document.addEventListener("pointerdown", ({ pointerType, target }) => {
if (pointerType === "mouse") target.dispatchEvent(mouse);
if (pointerType === "touch") target.dispatchEvent(touch);
});

const someElement = document.querySelector(".box");
someElement.addEventListener("mouseclick", () => {
console.log("Clicked with mouse");
});
someElement.addEventListener("touch", () => {
console.log("Touched with mobile device");
});
someElement.addEventListener("click", () => {
console.log("Clicked by some device (we don't know)");
});
.box {
position: absolute;
inset: 2em;
background: darkred;
padding: 1em;
}
<div class="box">A box with custom events</div>

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

Update: Please read blmstr's answer below 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.

Modernizr is a great, lightweight way to do all kinds of feature detection on any site.

It simply adds classes to the html element for each feature.

You can then target those features easily in CSS and JS. For example:

html.touch div {
width: 480px;
}

html.no-touch div {
width: auto;
}

And Javascript (jQuery example):

$('html.touch #popup').hide();


Related Topics



Leave a reply



Submit