Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cancel cluster expansion event #1101

Closed
eriknikulski opened this issue Mar 4, 2024 · 5 comments
Closed

Cancel cluster expansion event #1101

eriknikulski opened this issue Mar 4, 2024 · 5 comments

Comments

@eriknikulski
Copy link
Contributor

When clicking on a cluster I sometimes need to cancel the expansion event to do something else.
On the event clusterclick I have an event handler. Using event.originalEvent.stopPropagation(); and event.originalEvent.stopImmediatePropagation() I tried to cancel further propagation to avoid the expansion but that does not work. I also looked at spiderfied but this does not have a property originalEvent to access the browser event.

How would I go about canceling the expansion?

How to reproduce

const clusterLayer = L.markerClusterGroup({
    maxClusterRadius: 40,
});

this.map.addLayer(clusterLayer);

clusterLayer.on('clusterclick',  (event) => {
    event.originalEvent.stopPropagation();
});
  • Leaflet version I'm using: 1.7.5
  • Leaflet.MarkerCluster version I'm using: 1.4.6
  • Browser (with version) I'm using: Firefox 123.0
  • OS/Platform (with version) I'm using: Windows 10

What behaviour I'm expecting and which behaviour I'm seeing

Expected: can cancel cluster expansion

Seeing: cluster does expand

@IvanSanchez
Copy link
Member

It should be a fairly easy task to hack the _zoomOrSpiderfy method and check whether the event has been cancelled/defaultprevented.

@eriknikulski Maybe you want to try your hand at this?

@eriknikulski
Copy link
Contributor Author

Thanks for the info, I will give it a try.

@eriknikulski
Copy link
Contributor Author

@IvanSanchez one problem I am seeing is that _zoomOrSpiderfy is executed before any custom event registered on clusterclick. Therefore cancelling the event and avoiding the cluster spiderfy becomes a bit tricky. One could add a preexecution hook for _zoomOrSpiderfy, but I am not sure this is the best solution. Any suggestions?

@IvanSanchez
Copy link
Member

@eriknikulski I see. It makes sense. But I'm seeing that an event handler on the whole L.MarkerClusterClick does run before the default _zoomOrSpiderify, i.e.

markers.on('clusterclick', function (a) {

My approach at this point would be hacking on the bit of code that spawns a clusterclick event from a click event, i.e.:

fire: function (type, data, propagate) {
if (data && data.layer instanceof L.MarkerCluster) {
//Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget)
if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) {
return;
}
type = 'cluster' + type;
}
L.FeatureGroup.prototype.fire.call(this, type, data, propagate);
},

The chain of event handlers, as far as I can see, is as follows:

  • Leaflet DOM event handler on the cluster's <div>
  • L.Marker event handler (click)
  • L.Marker propagation to FeatureGroup
  • L.FeatureGroup event handler (click)
  • FeatureGroup propagation to MarkerCluster
  • MarkerCluster's fire (conversion to clusterclick)
  • MarkerCluster propagation to corresponding MarkerClusterGroup

So you should be able to intercept the click event and stop that one, or intercept the clusterclick event on the whole MarkerCluster before it propagates to the individual cluster.

Do keep in mind that the event triggering logic of MarkerCluster is old, as in legacy from Leaflet 0.x old. It's a bit finicky and it might not cover the usual mechanisms for event stopping that we are used to nowadays.

@eriknikulski
Copy link
Contributor Author

Thanks! I looked at it a bit more and found out if I attach the event handler before any layer is added to L.MarkerClusterGroup, this event handler fires before _zoomOrSpiderfy. This is because L.MarkerClusterGroup's events are registered with _bindEvents in onAdd, and this is called for adding layers. Therefore it is possible to register event handlers before the layers are added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants