From 34dc53812274638ceaa731c932ab5fd2f5139e76 Mon Sep 17 00:00:00 2001 From: Matt Walker Date: Fri, 10 Jan 2020 10:48:15 +0000 Subject: [PATCH] Stop events that originate with a removed target As discussed in https://github.com/openlayers/openlayers/issues/6948#issuecomment-565375694 The check to see if the target is within the "page" uses the viewport as the MapBrowserEventHandler instance adds it's listeners to the viewport. Using Node.contains appears to have a slight performance benefit over manually walking the DOM. --- src/ol/PluggableMap.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index fac2b185e2..f5252ed81b 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -934,11 +934,13 @@ class PluggableMap extends BaseObject { } let target = /** @type {Node} */ (mapBrowserEvent.originalEvent.target); if (!mapBrowserEvent.dragging) { - while (target && target !== this.viewport_) { - if (target.parentElement === this.overlayContainerStopEvent_) { - return; - } - target = target.parentElement; + if (this.overlayContainerStopEvent_.contains(target) || !this.viewport_.contains(target)) { + // Abort if the event target is a child of the container that doesn't allow + // event propagation or is no longer in the page. It's possible for the target to no longer + // be in the page if it has been removed in an event listener, this might happen in a Control + // that recreates it's content based on user interaction either manually or via a render + // in something like https://reactjs.org/ + return; } } mapBrowserEvent.frameState = this.frameState_;