Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer events dont work correctly on mobile

I have this fragment to handle pointer events:

container.on('pointerdown pointerup pointercancel pointerout pointerleave', console.log);

It works perfectly fine on my pc, but it's different on mobile. When I touch the screen it emits pointerdown (as it should), but as soon as I move my finger it instantly emits pointercancel, pointerout and pointerleave. When I lift my finger up it doesn't emit pointerup.

https://jsfiddle.net/zr8qeo7p/

like image 703
qucumbah Avatar asked Sep 15 '25 10:09

qucumbah


1 Answers

It is because brower intercepts gestures to make page scroll, page update, etc. To prevent this, you need to add in your CSS touch-action: none; for current element (It must be added before pointer event has occured).

Another way: use touch events (NOT pointer events) with passive: false and event.preventDefault() (not in promise, call immediately) to prevent browser to intercept gestures after pointer event has occured. Plus this listener must be invoked first so it must be added firstly (before your pointer events listeners). For example:

const onTouchMove = (ev:TouchEvent)=>{
  ev.preventDefault()
}
element.addEventListener(
  'touchmove',
  onTouchMove, 
  { passive: false }
)

But even after this, I can't see that pointerleave event works when i move finger out of element, but with mouse it works.

To make pointerleave and others to work i made this in pointerdown:

const onPointerDown = function (ev) {
  ev.target.releasePointerCapture(ev.pointerId)
}
element.addEventListener(
  'pointerdown',
  onPointerDown
)

Bonus: CSS have some useful properties along with touch-action: none; (it is inherited). user-select: none; - forbids selection (it is inherited). pointer-events: none; - makes element to be transparent for any ponter events (it is inherited).

like image 88
Ermac Avatar answered Sep 18 '25 11:09

Ermac