Search code examples
leafletleaflet.markercluster

Moving popup off screen closes popup unexpectedly (leaflet with leaflet.markercluster)


I don't understand why, but every time I open a popup and the popup is bigger than the screen or I move its anchor off screen, the popup closes. I tested it now and that just happens when leaflet.markercluster is in play. Run this snippet to see what I mean

With leaflet.markercluster

Popup closes when opened

var map = L.map('map').setView([38, -8], 7)

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

var markers = L.markerClusterGroup()

for (let i=0; i<100; i++) {

  let veryLongHtml = "popup " + i + "<br>"
  for (let j=0; j<1000; j++) {
    veryLongHtml+='a '
  }

  const popup = L.popup({
    closeOnClick: false,
    autoClose: false
  }).setContent(veryLongHtml);
  
  const marker = L.marker([
    getRandom(37, 39), 
    getRandom(-9.5, -6.5)
  ]).bindPopup(popup);
  
  markers.addLayer(marker)
}
map.addLayer(markers);

function getRandom(min, max) {
  return Math.random() * (max - min) + min;
}
#map {height: 200px}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/MarkerCluster.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.5.0/MarkerCluster.Default.min.css" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/leaflet.markercluster.js"></script>

<div id="map"></div>

Without leaflet.markercluster

Here it works OK, check:

var map = L.map('map').setView([38, -8], 7)

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

for (let i=0; i<10; i++) {

  let veryLongHtml = "popup " + i + "<br>"
  for (let j=0; j<1000; j++) {
    veryLongHtml+='a '
  }

  const popup = L.popup({
    closeOnClick: false,
    autoClose: false
  }).setContent(veryLongHtml);
  
  const marker = L.marker([
    getRandom(37, 39), 
    getRandom(-9.5, -6.5)
  ]).addTo(map).bindPopup(popup);
  
}

function getRandom(min, max) {
  return Math.random() * (max - min) + min;
}
#map {height: 200px}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<div id="map"></div>


Solution

  • I suspect this is due to the removeOutsideVisibleBounds option (enabled by default) which removes all Markers and Clusters which are far from the viewport to improve performance.

    You can simply give a try disabling this option:

    var markers = L.markerClusterGroup({
      removeOutsideVisibleBounds: false
    })
    

    Maybe it could be interesting to improve the Leaflet.markercluster library by preventing removing a Marker which popup is still open (and the option is enabled), to be discussed on the library repository...