5
votes

When using Mapbox GL JS in a browser, including using the emulation mode in Chrome, the event contextmenu responds to a long click/tap on the map. However, on a real device this event does not fire when the user taps and holds on the map.

What is the best way to listen for long taps on the map in Mapbox GL JS?

1
Which device? This could be a bug or an issue worth reporting at github.com/mapbox/mapbox-gl-js/issues - Steve Bennett
iOS. In the emulator in Chrome the tap-hold works as expected with the contextmenu event - jczaplew
Is the issue with Chrome on iOS, or a different browser? Think you should probably report it. - Steve Bennett
I have the same issue, works fine on desktop and emulator but not on real devices (tested on chrome android 4.4 and safari IOS 10). Did you manage to resolve the issue ? - ThunderDev
I have not found a solution yet. Might be worth filing a bug. - jczaplew

1 Answers

4
votes

Similar issue is discussed here.

My derived solution looks like this:

    if (Browser.isIos()) {
        init_ios_context_menu();
    } else {
        map.on('contextmenu', (e) => {
            show_context_menu_or_whatever(e);
        });
    } // end if

    function init_ios_context_menu() {
        let iosTimeout = null;
        let clearIosTimeout = () => { clearTimeout(iosTimeout); };

        map.on('touchstart', (e) => {
            if (e.originalEvent.touches.length > 1) {
                return;
            }
            iosTimeout = setTimeout(() => {
                show_context_menu_or_whatever(e);
            }, 500);
        });
        map.on('touchend', clearIosTimeout);
        map.on('touchcancel', clearIosTimeout);
        map.on('touchmove', clearIosTimeout);
        map.on('pointerdrag', clearIosTimeout);
        map.on('pointermove', clearIosTimeout);
        map.on('moveend', clearIosTimeout);
        map.on('gesturestart', clearIosTimeout);
        map.on('gesturechange', clearIosTimeout);
        map.on('gestureend', clearIosTimeout);
    };