So, I have a problem. I want to respond to a user pressing the mouse button (on desktop) or touching a div (on mobile). I'm trying to be compatile with evergreen browsers. This is what I tried so far:
- listen only to
mouseDown
event. This works on desktop but doesn't work in mobile if the user is dragging. I want the handler to be called as soon as the user touches the screen, no matter if they're moving their finger in the process. - listen only to
touchStart
event. This works on mobile and desktop, except for Edge and Safari desktop, which don't support touch events. - listen to both, then
preventDefault
. This causes a double handler call on Chrome mobile. It seems that touch events are passive to allow uninterrupted scrolling on mobile Chrome, sopreventDefualt
has no effect on them . What I get is a warning message saying"[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080"
in the console,preventDefault
is ignored and my event is called twice.
Obviously this can be solved by sniffing touch events, but the net is full of self-righteous rants on how one has to be device-agnostic and that it's dangerous to detect touch events before the user interacted.
So I guess that the question is: is there a way to do what I want to do without sniffing for touch events?
Below my sample React code:
function handler(e) {
console.log('handler called')
e.preventDefault()
}
export default function MyElement() {
return (
<div
onMouseDown={handler}
onTouchStart={handler}
>
Hello
</div>
)
}