mapsplugin / cordova-plugin-googlemaps

Google Maps plugin for Cordova
Apache License 2.0
1.66k stars 918 forks source link

Overflow scrolled content prevents map interaction #2819

Open glister opened 4 years ago

glister commented 4 years ago

Firstly, thank you for this plugin, it's worked great for us for years! I appreciate your hard work and have donated using the link below 👍

I'm submitting a ... (check one with "x")

OS: (check one with "x")

cordova information: (run $> cordova plugin list)

com.googlemaps.ios 3.9.0 "Google Maps SDK for iOS"
cordova-plugin-googlemaps 2.7.1 "cordova-plugin-googlemaps"
cordova-plugin-whitelist 1.3.4 "Whitelist"

Current behavior: If the map container div has a fixed height div beneath it which has overflow-y: auto and the content inside that div is scrolled down you can no longer interact with the map. It seems to be related to the plugin's ability to detect whether HTML content is over the map (i.e. zindex), it thinks the content in the div beneath it which is scrolled (but not visible because overflow) is actually over the map so touch gestures don't get through to the map.

Expected behavior: The map should be interactive when no HTML content is above the map container.

Screen capture or video record:

Screen-Recording-2020-07-31-at-1 Inspecting with safari shows the hidden list items that are scrolled out of the overflow image

Related code, data or error log (please format your code or data):

The code is the Hello World example with a little bit of extra HTML and CSS

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width">
    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript">
    document.addEventListener("deviceready", function() {
      var div = document.getElementById("map_canvas");

      // Create a Google Maps native view under the map_canvas div.
      var map = plugin.google.maps.Map.getMap(div);

      // If you click the button, do something...
      var button = document.getElementById("button");
      button.addEventListener("click", function() {

        // Move to the position with animation
        map.animateCamera({
          target: {lat: 37.422359, lng: -122.084344},
          zoom: 17,
          tilt: 60,
          bearing: 140,
          duration: 5000
        });

        // Add a maker
        var marker = map.addMarker({
          position: {lat: 37.422359, lng: -122.084344},
          title: "Welecome to \n" +
                 "Cordova GoogleMaps plugin for iOS and Android",
          snippet: "This plugin is awesome!",
          animation: plugin.google.maps.Animation.BOUNCE
        });

        // Show the info window
        marker.showInfoWindow();

      });

    }, false);

    </script>
    <style type="text/css">
    body, html {
        height: 100%;
        padding: 0;
        margin: 0;
    }
    #map_canvas { /* Must bigger size than 100x100 pixels */
      width: 100%;
      height: 50%;
    }
    #list {
        height: 50%;
        width: 100%;
        overflow-y: auto;
    }
    .item {
        height: 2rem;
    }
    button {
      padding: .5em;
      margin: .5em;
    }
    </style>
  </head>
  <body>
    <div id="map_canvas">
      <button id="button">Click me!</button>
    </div>
    <div id='list'>
        <div class='item'>Item 1</div>
        <div class='item'>Item 2</div>
        <div class='item'>Item 3</div>
        <div class='item'>Item 4</div>
        <div class='item'>Item 5</div>
        <div class='item'>Item 6</div>
        <div class='item'>Item 7</div>
        <div class='item'>Item 8</div>
        <div class='item'>Item 9</div>
        <div class='item'>Item 10</div>
        <div class='item'>Item 11</div>
        <div class='item'>Item 12</div>
        <div class='item'>Item 13</div>
        <div class='item'>Item 14</div>
        <div class='item'>Item 15</div>
        <div class='item'>Item 16</div>
        <div class='item'>Item 17</div>
        <div class='item'>Item 18</div>
        <div class='item'>Item 19</div>
        <div class='item'>Item 20</div>
    </div>
  </body>
</html>

Support this plugin activity Supported!

wf9a5m75 commented 4 years ago

Thank you for your donation :) And it seems a bug. Please specify hidden or scroll instead of auto. I will fix this bug in the next version.


One tip. This plugin checks all position, dimension, and some CSS properties to detect the touch position. So, if the list has bunch of child elements, the performance goes down.

To prevent this, please use ShadowDom


For example, there is a list like this.

<style>
  .list {
    width:300px;
   height:300px;
    overflow-y:scroll
  }
  .list-item {
     width: 100%;
     height: 50px;
  }
</style>
<div class="list">
  <div class="list-item">item</div>
  <div class="list-item">item</div>
  <div class="list-item">item</div>
  ..... (repeat 100000 items)
  <div class="list-item">item</div>
</div>

If you use shadowDom, this plugin does not inspect inside the element.

<div class="list" id="list"></div>   <--- Maps plugin checks only this element

<script>
  var list = document.getElementById("list");

  var container = list.attachShadow({mode: 'open'});  // or 'close'
  for (var i = 0; i < 100000; i++) {
    var item = document.createElement("div");
    item.addClasses("list-item");
    container.appendChild(item);
  }
</script>

In this case, this plugin can reduce the number of checking elements significantly.

glister commented 4 years ago

Thanks @wf9a5m75 , Using overflow-y: scroll didn't seem to fix the problem, but using shadowDom solves the problem.

Look forward to the next version 👍