Mapbox-gl-js: Set `touch-action: none` on the map container

Created on 11 Feb 2017  ·  11Comments  ·  Source: mapbox/mapbox-gl-js

mapbox-gl-js version:

Steps to Trigger Behavior

  1. While using mapbox gl-js on a mobile device or any device that uses (touch) to move the map, an error is thrown due to the event listener being treated as passive. I even looked into this on your own site, it does the same on any mapbox application using the gl-js version.

Expected Behavior

Move fluid

Actual Behavior

Moves slow, clunky

bug release blocker

Most helpful comment

We ran into this issue preparing for a trade show last week using some Win10 touch kiosks.

In order to keep touch events ultra-responsive the standards-makers are proposing and appearing to move to disallow 'active' event handlers -- that is to say that javascript event handlers will only process asyncronously with whatever the native touch handler is doing (zoom, pan, scroll, etc.)

The way to stop the native handlers is to set the touch-action: none in the CSS; this seems to be a good overall workaround unless you want to still support touch scrolling of the page until the map is 'activated' by a tap or something. Chrome 56 also has a bug where touch-action: none does not stop all instances of pinch-zoom. It's fixed in Chrome 57, currently in the Beta channel. There is absolutely no workaround that can be done in js/css/html for Chrome 56. The only fix is to completely disable pinch zoom via commandline argument.

I noticed but did not investigate why the touch events dont work at all in Edge anymore (did they ever?)

All 11 comments

Could be related to the issue React has with recent Chrome (56): https://github.com/facebook/react/issues/8968

@Scarysize good find -- that appears to be the likely culprit.

Our touchmove and touchend event handlers for DragPanHandler, DragRotateHandler, and TouchZoomRotateHandler all do need to use preventDefault(), so we'll probably need to add {passive: false} for those. Possibly also for the wheel/mousewheel events used by ScrollZoomHandler.

Aside from those, I think we should also do an audit of any other touch event handlers we register and determine whether we (a) are using preventDefault, and (b) actually _need_ to be. (For example, the touchstart events in the Drag*Handlers.) If the answer is yes, then we should likewise set {passive: false}; otherwise, it would still be good to be explicit and set {passive: true}.

@anandthakker Was this something that you guys figured out? I'm still consoling errors in my application. Thanks!

@anandthakker possibly related to this is the fact that mapbox-gl-js stopped correctly working with windows 10 mult-touch gestures at some point not long ago. E.g. the demo at https://www.mapbox.com/mapbox-gl-js/examples/ will scale the entire page if I attempt to pinch to zoom in (although zoom out works correctly), and will also invoke chrome 'go back' gesture if I try to pan the map to the right.

Both of these scenarios worked fine a couple months ago, possible regression?

We ran into this issue preparing for a trade show last week using some Win10 touch kiosks.

In order to keep touch events ultra-responsive the standards-makers are proposing and appearing to move to disallow 'active' event handlers -- that is to say that javascript event handlers will only process asyncronously with whatever the native touch handler is doing (zoom, pan, scroll, etc.)

The way to stop the native handlers is to set the touch-action: none in the CSS; this seems to be a good overall workaround unless you want to still support touch scrolling of the page until the map is 'activated' by a tap or something. Chrome 56 also has a bug where touch-action: none does not stop all instances of pinch-zoom. It's fixed in Chrome 57, currently in the Beta channel. There is absolutely no workaround that can be done in js/css/html for Chrome 56. The only fix is to completely disable pinch zoom via commandline argument.

I noticed but did not investigate why the touch events dont work at all in Edge anymore (did they ever?)

Interesting. Well thank you guys for the information. It's not the biggest issue, it's honestly just a bit annoying on mobile. Hopefully Chrome 57 will fix this.

@kavada it is a big issue for me in a fullscreen app on a touch table. While zooming the map GUI-Elements get zoomed as well until they are out of the viewport.

@indus I was able to get touch working properly by setting style.touchAction = 'none' on the mapbox element as per @johnlaur suggestion. You should be able to do the same.

Retitling to reflect the preferred solution of using touch-action: none as described here. Passing {passive: false} to addEventListener() when touch-action: none will do is discouraged.

Note that we should not unconditionally set touch-action: none on the map container, but rather use more targeted rules depending on which handlers are enabled, similar to what was implemented in Leaflet in this PR.

Linking upstream issue for reference: https://github.com/WICG/interventions/issues/18

@bicubic .... YES Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PBrockmann picture PBrockmann  ·  3Comments

foundryspatial-duncan picture foundryspatial-duncan  ·  3Comments

jfirebaugh picture jfirebaugh  ·  3Comments

iamdenny picture iamdenny  ·  3Comments

stevage picture stevage  ·  3Comments