I am trying to create a popup on a marker, which contains buttons, but I am having trouble with events not firing from the buttons on the marker popup.
I create the popup with
function addMarker(e) {
var marker = new L.Marker(e.data.latlng,{clickable:true, draggable:true});
map.addLayer(marker);
var content = "Marker " +
"" +
"";
marker.bindPopup(content);
marker.on('dragend',onMarkerDragEnd);
map.closePopup(popup);
}
And try to catch the event from the button with:
jQuery('#deleteMarker').live('click',function(e) { alert('delete'); });
Similar code that just adds a popup to the map works, but the above does not when the popup is bound to a marker.
I have tried modifying Popup.js to remove the disableClickPropagation command (line 81 - https://github.com/jones139/Leaflet/commit/117db3515c6b8070e0d2c42ff4bc1030fe5feef4), and this gets my events working, but the clicks also propagate down to the map. Therefore I think it is an issue in Leaflet somewhere?.....Or I may be doing it wrong!
Stopping propagation to the map inside popup is intended by design, and jQuery "live" depens on propagation to the document. So I'd suggest not using jQuery live function in this case. The best practice for buttons inside popups is to create the buttons dynamically as DOM objects (using document.createElement, document.appendChild, etc.) and then pass a DOM object instead of HTML string to the bindPopup method.
Thanks - I'll try that!
Hi, i would love to see the option to not disable propagation from clicks on popups. Attaching handlers to every single popup is much less efficient than having a delegate or live handler covering all at once, and it is harder to avoid resource leaks too.
I have a custom TileLayer that places dom elements within the tiles, and the events propagate from there, and it seems to work just fine; I don't see why it would be harmful or undesirable for events to propagate from popups either. Any clarification as to why stopping propagation is intended by design?
Ok, after playing with this and adding the option to let events propagate I can see why this is necessary now: otherwise any click within the popup propagates to the map, which closes the popup (a general feature of leaflet - clicking on the map will close any open popups). Some more work would be necessary to allow this to work as a viable option for delegate handlers. I know it works in google maps, so seems like a reasonable feature. Perhaps some way of marking the event so the map knows to not close the popup.
Are there any more thoughts on this? I agree with the comments in issue 765, it seems like it should be possible to modify the map click handler to detect if a click originated in a marker/popup and just ignore that case.
I am using the Leaflet clusterer with tens of thousands of markers and it seems like event delegation would make a lot of sense here so I could avoid creating thousands of event listeners. I would like to be able to bind one listener to receive any click on a marker and then dynamically create a popup on the marker to also avoid creating thousands of popup.
This seems like a reasonably small improvement that could be very helpful for resource/performance concerns.
Just a followup on myself, it appears that the Leaflet clusterer plugin allows me to register a single event listener on a cluster or markers, so I guess that works ok for what I want to do. However, I think it still makes sense to make this possible in general.
The reason this works in L.MarkerCluster is that it is a L.FeatureGroup, which you can set event listeners on and it will set them on all of its child markers.
Bummer if it isn't doing it in a more efficient way that just adding the event listener to all thousands of the markers... Thanks for the comment.
OK, done as suggested by @krosaen & @rickhall (marking click events as ignored by map) — seems to work, yay! Guys, could you please try that out and tell if it works well for you?
This was happening to me as well, in my attempts to use Leaflet with jQuery Mobile in wq.app. I tested out the new code and it appears to be working with my custom navigation event handlers. Thanks!
@sheppard Awesome!
Hi,
It seems that this bug now occurs only in a specific setup...
I'm developing a hybrid app that is ported to android and ios. I'm running leaflet v.1.0.3. This version fixed this behavior for web and android setups but in ios events on elements within popup do not fire.
This is my original code that does work for android and web:
var container = $("<div class='leaflet-marker-actions-wrapper' />");
var icon = $("<button class='button icon icon-back'></button>");
container.on("click", ".icon-back", function (e: JQueryEventObject) {
console.log("action fired");
});
container.append(icon);
var popup: L.Popup = L.popup(popupOptions).setContent(container[0]);
marker.bindPopup(popup).openPopup();
I've tried multiple approaches also:
icon.on("click", function (e: JQueryEventObject) {
console.log("action fired");
});
icon.click(function (e: JQueryEventObject) {
console.log("action fired");
});
L.DomEvent.addListener(container.get(0), "click", function () { console.log("action fired"); });
None of those log anything in the console. Yet, the click on marker works perfectly.
Unfortunately I can't supply an example of this behavior since it should be actually tested on an iOS device.
BTW the same behavior is experienced on iOS 9.1 and 10.2.1.
Can anything be done with it?
Thanks in advance
Well, found the solution.
It's not the leaflet, it's the iOS. Just replace the click by mousedown or mouseup events and it will work.
Most helpful comment
Well, found the solution.
It's not the leaflet, it's the iOS. Just replace the
clickbymousedownormouseupevents and it will work.