When you add Markers or other Overlays on top of the map, the pointer events are still propagated to the map.
For example if we render a "control panel" on top of the map in the corner, we can still drag the map around through the overlay. The only way around this issue is to render such content outside of the map component
The same problem happens with Markers. In my case I am adding a onClick handler on the Marker itself and adding an additional onClick markers on the map itself. Both handlers are fired even if we specify:
onMarkerClick(e) {
e.preventDefault()
e.stopPropagation()
}
onMapClick(e) {
// -> still fired
}
I am attempting to create something similar in nature to this.
https://www.mapbox.com/mapbox-gl-js/example/toggle-layers/
Is there any comments on this? I have tested in simple react parent/child components, event can be stopped in event handler in child component which would not propagate to parent.
But dblClick event can always pass to mapComponent causing zoom, stopPropagation does not work. Weird. For example: https://alex2wong.github.io/react-mapglDemo/
Where is the problem ?
I just ran into this as well. It appears be because the eventCanvas is a parent of the overlays container where the children are inserted. It is present in the examples too, for example in https://uber.github.io/react-map-gl/#/Examples/markers-popups you can drag the map while on top of the overlays
My work around is to put my controls outside of the react-map-gl component inside of passing them as children.
The problem here is caused by us using hammer.js under the hood. The click and doubleClick events are triggered by pointerUp, which always fires before the native click and dblClick.
@ericsoco @ibgreen @shaojingli
@aindeev @alex2wong @kriscarle In your use cases, would it work if the Marker/Popup components by default blocks map interaction (click and drag do not propagate) but also offers a prop to turn it on?
Another alternative is to render the controls outside of the event canvas, which will also block map interaction by default, and use css pointer-events: none if you want them to be non-blocking.
I'm not sure if this fix was solved for @aindeev , but this propagation issue is still affecting my app despite the fix.
If on the ReactMapGL you specify an onClick function, then have a Popup component as a child, any onClick callback functions in the Popup component will still propagate to the map.
Am I missing something? I've looked through the examples and documentation without luck
@heathercodes You can block the click event from propagating by setting captureClick: true on the Popup component (see https://github.com/uber/react-map-gl/pull/377).
The long explanation is that, to handle pointer/touch gestures, react-map-gl registers its event handlers using the native JavaScript API. Calling stopPropagation on React's synthetic events does not block the native events from firing.
Thanks for responding @Pessimistress . I have tried setting the flag to false on the Popup component, but this does nothing. The only thing that stops the propagation is when I remove the onClick callback function from the ReactMapGL component itself.
Obviously, this isn't ideal, as I'm trying to capture location when the user clicks on the map, and display it in a popup.
@heathercodes Sorry I mistyped, it should have be captureClick: true (edited original message).
Though after a quick test it does not seem to function as expected. I'll investigate.
@heathercodes Give 3.2.10 a try.
thanks for the quick turn around @Pessimistress. I tried the new version, but am still seeing the same behaviour.
@heathercodes Could you post your code and steps to reproduce the problem here?
hey @Pessimistress , looks like I forgot to re-enable captureClick on the Popup component from the last test I did on this bug. I took it off again, and things are functioning properly; 3.2.10 resolves this issue. Thanks for looking into this so quickly! 馃憤
Any idea how I could do this in a non-Popup component? Catching the scroll, click, etc event in a custom controller does not seem to indicate which element I clicked; it just shows I clicked the map.
guys, great library but this behavior is annoying... I think I will end up bypassing these nice but "nosy" event mjolnir handlers and attach directly to the map on the onLoad callback, since mapbox already implements 'click' and other events. It's a pity, though.
Even context menu is intercepted by onClick, which does not make sense to me
e.g.
<InteractiveMap
...
ref={mapViewRef}
oLoad={()=>{
const map = mapViewRef.getMap()
map.on('click', mapClickHandler)
}}
/>
But I'd appreciate a cleaner solution
Even worse, the div.overlays intercepts all the mouse events, so we have to force it via CSS 馃槥
I added a rule in a parent component stylesheet/style component
div.overlays {
pointer-events: none;
}
I would suggest an option to use mapbox handlers instead of mjolnir's, or at least make them less invasive.
I had to do this since I added some extra map controls.
Huge downside: all children of overlays are cut out, including those from react-map-gl-draw 馃槶
Most helpful comment
Any idea how I could do this in a non-Popup component? Catching the scroll, click, etc event in a custom controller does not seem to indicate which element I clicked; it just shows I clicked the map.