The only way to detect touch with JavaScript
If you ask stack overflow “how to detect touch with JavaScript” you’ll get a lot of answers that all have one thing in common: they have nothing to do with humans.
In my not-even-close-to-humble opinion, all of these answers are wrong, but it’s not the fault of the answerers. It’s the fault of the askerers. Why on earth would you want to know if your user is looking at a device that responds to the touch?
We want to detect human touch, not device touch. I reckon that’s important enough to be repeated in a big font.
We want to detect human touch, not device touch.
We don’t care if the user’s browser throws an exception if we try document.createEvent(‘TouchEvent’) or if ‘ontouchstart’ in window or window.DocumentTouch && document instanceof DocumentTouch or navigator.msMaxTouchPoints > 0 or any other ridiculously obscure and brittle expression evaluates to true, because not one of these has anything to do with humans and their grubby little fingers.
It’s kinda like if you’ve just arrived at the airport and your friend that was coming to pick you up isn’t there. You want to know if they’re at least on their way to pick you up. So you call and ask if they’re currently strapped to a chair. Sure, a lot of the time when someone’s driving they’re strapped to a chair, but you can drive without being strapped to a chair, and you can be strapped to a chair without being in a car (YOLO, amiright?).
So let’s work on the question. We really just want to know if the user is using their fingers to interact with our site.
As luck would have it, answering this question is really, really easy:
For the sake of thoroughness, here’s a more detailed example.
But wait, I want to know before the user touches the screen
You can’t*.
FIN
I’m going to call this end of part one. I hope that I have convinced at least a few people that detecting human touch instead of device touch is not only better, but easier.
But I’ve got more rant left in me, so onward I forge…
WHY?
Why are you doing what you’re doing? Think of your potential users in these scenarios:
- using a mouse and a desktop computer
- using a mouse plugged into an Android tablet/laptop thingy, resting on the thigh of a neighbor on a plane
- using a tiny crappy laptop touch-pad
- using their sticky fat fingers on an iPhone 4
- using their slender, elegant finger on a 13" iPad
- using the pen on a Surface Pro
Which of those situations do you want to detect and treat differently? Hmmm?
Here’s the scenarios for wanting to ‘detect touch’ I’ve come across recently:
Bigger tap targets for the touchers
So you want to make tap targets nice and fat for people touching the screen.
I put it to you that you’re going about this the wrong way. I further suggest that you provide 50px tap targets for everyone! Anyone that has trouble seeing, or moving a mouse, or sausages for fingers will thank you.
But OK, you have something against people with Parkinson’s and want to only provide comfortable click targets to people using their fingers. You don’t want to waste real estate on big buttons if the user is ‘touching’ the screen with a pen, right? So the question becomes “how accurately can the user interact with the screen”.
You really want to know the girth of their touch apparatus, don’t you.
Pointer Events to the rescue. This is a great little API that is slowly** getting implemented.
Different hover behaviour for the touchers
Let’s say we have a bunch of little ‘info’ icons throughout our site. For mouse users, these should display a handy hint on hover. But mobile users don’t have hover so we want to make them show up when tapped.
Hmm, does this have anything to do with touch? Nope. It has to do with hover, right? Again, let’s come up with a better question: “will I be able to detect when a user is hovering over my icons?”
Once more we are blessed with a very simple answer to our question:
Swipe interactions for the touchers
You are making a carousel thingy. You have predicted that people want to swipe left and right through images with their finger on a screen, but hate when they are able to do the same thing with their finger on a touch pad. So you detect for a ‘touch device’ and only set up swipe interaction for users with touch-enabled devices.
My suggestion, stop discriminating against non-touchers. Allow your user to swipe with fingers-on-screen, fingers-on-trackpad, or mouse, or pen, or whatever input they gosh-darn want.
Bonus: it’s less work!
Any other examples…
No matter what your reason for wanting to ‘detect touch’, try and rephrase the question. Be specific. What, exactly, do you want to know about your user’s situation. Armed with a better question, you will come up with a better answer.
* I have a funny feeling some people will carry on trying to detect touch devices right up to the day that Apple launches a touchscreen MacBook.
** A little bit of my fondness for Google died the day I read that they wouldn’t implement the PointerEvents w3c recommendation, because they didn’t want to. 2 years later and I’m glad to say pointer events are working in Chrome.
✉️ Subscribe to Codeburst’s once-weekly Email Blast, 🐦 Follow Codeburst on Twitter, and 🕸️ Learn Full Stack Web Development.