OpenTreeMap / otm-core

OpenTreeMap is a collaborative platform for crowdsourced tree inventory, ecosystem services calculations, urban forestry analysis, and community engagement.
www.opentreemap.org
Other
186 stars 88 forks source link

Map layer selector does not open on iPad #3250

Closed dboyer closed 6 years ago

dboyer commented 6 years ago

Reported by a client.

  1. Open any tree map on an iPad.
  2. Click the map layer selector.
  3. Nothing happens

A client reported this using the most recent iOS version. I saw the same issue on my ancient iPad running version 9.3.5.

jwalgran commented 6 years ago

I reproduced this in the simulator with multiple iOS versions.

jwalgran commented 6 years ago

When using a desktop browser, the layer selector appears on hover. We need to update event handling so that a click will also trigger the layer selector.

jwalgran commented 6 years ago

I created a test page with the current OTM production Leaflet version (1.0.3) and the layer selector works in the iOS simulator.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <title>Leaflet map</title>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css" rel="stylesheet"/>
        <style>
         body {
             padding: 0;
             margin: 0;
         }
         html, body, #map {
             height: 100%;
             width: 100%;
         }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet-src.js"></script>
        <script>
         var map = L.map('map').setView([ 39.961318, -75.154188 ], 12);
         var layers = {
             'Light': L.tileLayer(
                 'https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}@2x.png', {
                     maxZoom: 18,
                 }),
             'Dark': L.tileLayer(
                 'https://cartodb-basemaps-a.global.ssl.fastly.net/dark_all/{z}/{x}/{y}@2x.png', {
                     maxZoom: 18,
                 })
         }
         layers['Light'].addTo(map);
         var layersControl = L.control.layers (layers, null, {
             autoZIndex: false
         }).addTo(map);
        </script>
    </body>
</html>
jwalgran commented 6 years ago

I attached the Safari debugger to the iOS Simulator and set breakpoints inside the Leaflet code. It appears that click events on the layer selector are not making it to Leaflet. Breakpoints set on the attached handler functions are never hit.

jwalgran commented 6 years ago

This post and the jsfiddle it links to show a similar behavior in mobile safari.

jwalgran commented 6 years ago

Setting a pointer style and setting onclick="" did not resolve the issue.

I also tried delaying creation of the layer selector with setTimeout but it is still not clickable in Mobile Safari.

jwalgran commented 6 years ago

I started reimplementing the layer selector by copying the exiting Leaflet code and modifying it to try and resolve the issue. Through that process I discovered that removing this one call resolved the issue

disableClickPropagation(container);

https://github.com/Leaflet/Leaflet/blob/ffcfcc1ba9a5b43ceff729ad87353fb768cfb7c4/src/control/Control.Layers.js#L149

However removing this call results in the layer selector collapsing after an item is selected, rather than staying open. I am going to try replacing the disableClickPropagation method with something else.

// @function disableClickPropagation(el: HTMLElement): this
// Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`,
// `'mousedown'` and `'touchstart'` events (plus browser variants).
disableClickPropagation: function (el) {
    var stop = L.DomEvent.stopPropagation;

    L.DomEvent.on(el, L.Draggable.START.join(' '), stop);

    return L.DomEvent.on(el, {
        click: L.DomEvent._fakeStop,
        dblclick: stop
    });
},

https://github.com/Leaflet/Leaflet/blob/ffcfcc1ba9a5b43ceff729ad87353fb768cfb7c4/src/dom/DomEvent.js#L176-L188