So, I've run across an interesting problem while working on a Web application for the Microsoft Surface.
I want to add event listeners for when a user interacts with a DOM element. Now I can do:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
} else {
//Attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
}
If the device didn't have a mouse input, this problem would be simple and the above code would work just fine. But the Surface (and many new Windows 8 computers) have BOTH a touch and mouse input. So the above code would only work when the user touched the device. The mouse event listeners would never be attached.
So then I thought, well, I could do this:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
}
//Always attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
Devices that don't support touch wouldn't have the events attached, but a device that uses touch will register its handlers. The problem with this though is that myFunc()
will be called twice on a touch device:
myFunc()
will fire when "touchstart" is raised- Because touch browsers typically go through the cycle touchstart -> touchmove -> touchend -> mousedown -> mousemove -> mouseup -> click,
myFunc()
will be called again in "mousedown"
I've considered adding code tomyFunc()
such that it calls e.preventDefault()
but this seems to also block touchend as well as mousedown / mousemove / mouseup on some browsers (link).
I hate doing useragent sniffers, but it seems as if touch browsers have variations in how touch events are implemented.
I must be missing something because it seems that surely these JavaScript implementations were decided with possibility of a browser supporting both a mouse and touch!