Created
March 7, 2017 15:11
-
-
Save perliedman/84ce01954a1a43252d1b917ec925b3dd to your computer and use it in GitHub Desktop.
Click through multiple layers of Leaflet VectorGrid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Since overlays are VectorGrid layers with canvas rendering, | |
// they don't support clicking through them (the topmost canvas | |
// swallows the event, lower layers will not see it). | |
// We workaround this by this hack (inspired by | |
// http://www.vinylfox.com/forwarding-mouse-events-through-layers/): | |
// | |
// All overlays are in their own Leaflet pane. When a click hits a | |
// layer in the pane, we first handle the event like normal, and then | |
// hit the event handler below this comment. | |
// | |
// The event handler will hide the original target layer's DOM element, | |
// and then find out which DOM element is under it, and re-dispatch the same | |
// event on that element, and continuing this process until all layers | |
// have been dispatched, or abort if a layer's event handler stops the | |
// event. | |
// | |
// We currently only do this for clicks, since hiding and redisplaying | |
// elements is a performance hog if you do it in for example mousemove. | |
overlayPane = map.createPane('my-overlays'); | |
L.DomEvent.on(overlayPane, 'click', function(e) { | |
if (e._stopped) { return; } | |
var target = e.target; | |
var stopped; | |
var removed; | |
var ev = new MouseEvent(e.type, e) | |
removed = {node: target, display: target.style.display}; | |
target.style.display = 'none'; | |
target = document.elementFromPoint(e.clientX, e.clientY); | |
if (target && target !== overlayPane) { | |
stopped = !target.dispatchEvent(ev); | |
if (stopped || ev._stopped) { | |
L.DomEvent.stop(e); | |
} | |
} | |
removed.node.style.display = removed.display; | |
}); |
Also, in case the above I said is implemented, click
events are somehow disabled when adding GeoJSON layers to their panes.
I used mousedown
instead as a workaround.
Also, if the web map is also for use of mobile devices, you might have already used leaflet-touch-helper.js
to make line features easier to click. In that case, you'll also need to add mousedown
event to the listeners in leaflet-touch-helper.js
, otherwise the extraWeight-clickables will not work.
Unlike vector tile layers though, mouseover
and mouseout
don't need to be reconstructed.
https://gis.stackexchange.com/a/323983/210705 this saved my life, this plugin worked like a charm: https://github.com/danwild/leaflet-event-forwarder.git
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found the cursor not functioning properly as having multiple layers should do: the cursor changes to
<pointer>
(the "finger") only at the top vector tiles. Here's the workaround I did:For the event dispatching, dispatch also the
mousemove
(instead ofmouseover
) event, additional to theclick
event:Then when adding the vector tile layers, rebuild the mouse cursor change by assigning
$('.leaflet-tile-loaded')
properties onmouseover
andmouseout
events.Hope you find this helpful.