Leaflet / Leaflet

🍃 JavaScript library for mobile-friendly interactive maps 🇺🇦
https://leafletjs.com
BSD 2-Clause "Simplified" License
41.56k stars 5.85k forks source link

remove() doesn't check that parent has that child causing an exception #8432

Open MaximRikel opened 2 years ago

MaximRikel commented 2 years ago

Checklist

Steps to reproduce

Remove function causes an exception when using Leaflet.markercluster.

function remove(el) { var parent = el.parentNode; if (parent) { parent.removeChild(el); } }

When zooming in on a cluster that contains multiple markers at the same location I sometimes get an exception:

Uncaught DOMException:
Failed to execute 'removeChild' on 'Node': The node to be removed is no longer a child of this node.
Perhaps it was moved in a 'blur' event handler?
    at _remove (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:2136:1)
    at _removeIcon (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:7240:1)
    at onRemove (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:7088:1)
    at removeLayer (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:6319:1)
    at removeLayer (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:6459:1)
    at removeLayer (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:6593:1)
    at <anonymous> (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1801:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1828:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursively (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1841:1)
    at _recursivelyRemoveChildrenFromMap (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1782:1)
    at _animationZoomIn (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1257:1)
    at _mergeSplitClusters (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:1138:1)
    at _zoomEnd (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js:978:1)
    at fire (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:624:1)
    at _moveEnd (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:3996:1)
    at _onZoomTransitionEnd (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:4463:1)
    at _catchTransitionEnd (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:4381:1)
    at handler (/Users/maximfalkor/Projects/Falkor/atreyu/node_modules/leaflet/dist/leaflet-src.js:2555:1)

Expected behavior

The function should check that the parent contains this child before attempting to remove

Current behavior

Exception

Minimal example reproducing the issue

No response

Environment

mourner commented 2 years ago

I'm not sure it should — it's helpful to see this error because it usually indicates a deeper issue we should find the root cause of. Can you create a minimal test case of a situation where this happens? (I see it's something related to the markercluster plugin?)

MaximRikel commented 2 years ago

I wasn't able to recreate this bug with markercluster base code and I'm not at liberty to share my clients code. I hope you are able to solve this without an example but if not I'll try to find the time to write something reproducible.