Is there any clear and reliable (and described) mechanism to control mouse events for overlapping layers in Mapbox GL JS? For example, I have 3 overlapping layers, but want that click handler was called only for the layer that is on top, but not for all 3 layers - is that possible somehow? For now, as a workaround, I track MouseEnter and MouseLeave events and call an appropriate handler based on that. But I don't like this solution at all because it spoils my code with excess logic.
Is there any clear and reliable (and described) mechanism to control mouse events for overlapping layers in Mapbox GL JS? For example, I have 3 overlapping layers, but want that click handler was called only for the layer that is on top, but not for all 3 layers - is that possible somehow? For now, as a workaround, I track MouseEnter and MouseLeave events and call an appropriate handler based on that. But I don't like this solution at all because it spoils my code with excess logic.
Share Improve this question asked May 11, 2018 at 14:09 Anton PilyakAnton Pilyak 1,1302 gold badges17 silver badges36 bronze badges1 Answer
Reset to default 17It is not very clear what problem you're experiencing. If you have three layers (layer1, layer2, layer3) where the top layer is layer1 and you only want to respond to click events for it, you do:
map.on('click', 'layer1', function(e) {...})
If this is not what you mean, perhaps clarify what you mean by "overlapping layers" and "want that click handler was called only for the layer that is on top". Also, please provide your current code, with an example of what the problem is.
EDIT
A click event can apply to all layers beneath the clicked point, so if you want to capture several layers in a single click event, and identify the topmost item clicked:
map.on('click', function(e) {
let f = map.queryRenderedFeatures(e.point, { layers: ['layer1','layer2','layer3'] });
if (f.length) {
console.log(f[0]); //topmost feature
}
});
But, if you want to capture the click event for just a single layer you can specify that layer in two ways:
map.on('click', function(e) {
let f = map.queryRenderedFeatures(e.point, { layers: ['layer1'] });
if (f.length) {
console.log(f[0]);
return;
}
f = map.queryRenderedFeatures(e.point, { layers: ['layer2'] });
if (f.length) {
console.log(f[0]);
return;
}
f = map.queryRenderedFeatures(e.point, { layers: ['layer3'] });
if (f.length) {
console.log(f[0]);
}
});
Or as in the original answer above:
map.on('click', 'layer1', function(e) {
let f = map.queryRenderedFeatures(e.point, { layers: ['layer1'] });
if (f.length) {
console.log(f[0]);
}
return;
});