Reputation: 10718
I have a problem where my mouseenter
, mouseleave
, mouseover
and mouseout
events get swallowed and do not fire.
Basically there's a map on my page which I add markers (divIcons) and draw paths on. Separate from this map, I have a tooltips and context menus that attach to events on the various markers and paths in order to be activated. The map does not know anything about the tooltips or context menu so the events are attached by a configuration file that uses jquerys on
method.
Assuming the divIcons have the class markerElement
the code looks like this:
$(document).on('mouseenter', '.markerElement', function(){ console.log('ENTER'); });
$(document).on('mouseleave', '.markerElement', function(){ console.log('LEAVE'); });
I've tracked the problem down to the stopPropagation method on line 6484 of leaflet-src.js version 0.7.3. If I comment out e.stopPropagation()
my events work, I'm a little confused to the purpose of this method in relation to leaflet.
Is there any other way I can get the mouseenter
and mouseleave
events to attach to dynamically created elements on the map without the map knowing about it and without changing the leaflet source?
The context menu and tooltip code works on other elements that are not on the map, so a general solution that can dynamically pick out elements based on some kind of selector would be ideal.
Thanks for any ideas
Upvotes: 0
Views: 1482
Reputation: 28638
Perhaps it's an option for you to disable all events on L.Marker
and L.Path
, you can do that by using 'clickable': false
in their options.
It's also possible to disable only certain events by creating a custom marker extended from L.Marker
, here i commented out the mouseover
and mouseout
:
L.CustomMarker = L.Marker.extend({
_initInteraction: function () {
if (!this.options.clickable) { return; }
// TODO refactor into something shared with Map/Path/etc. to DRY it up
var icon = this._icon,
events = ['dblclick', 'mousedown', /*'mouseover', 'mouseout',*/ 'contextmenu'];
L.DomUtil.addClass(icon, 'leaflet-clickable');
L.DomEvent.on(icon, 'click', this._onMouseClick, this);
L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
for (var i = 0; i < events.length; i++) {
L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
}
if (L.Handler.MarkerDrag) {
this.dragging = new L.Handler.MarkerDrag(this);
if (this.options.draggable) {
this.dragging.enable();
}
}
}
});
Here's an example on Plunker: http://plnkr.co/edit/naWEPz?p=preview
If you want to remove the stopPropagation on L.Marker
's clickevent you can do so also by extending L.Marker
in a similar way:
L.CustomMarker = L.Marker.extend({
_onMouseClick: function (e) {
var wasDragged = this.dragging && this.dragging.moved();
/*if (this.hasEventListeners(e.type) || wasDragged) {
L.DomEvent.stopPropagation(e);
}*/
if (wasDragged) { return; }
if ((!this.dragging || !this.dragging._enabled) && this._map.dragging && this._map.dragging.moved()) { return; }
this.fire(e.type, {
originalEvent: e,
latlng: this._latlng
});
}
});
Kind of hackish but it's supposed to work, you can do the same with other method in L.Marker
that calls stopPropagation
. The same goes for L.Path
, just extend it with the methods you want to change and i think you're good to go (didn't know how to test this properly, so i didn't :D) Good luck!
Upvotes: 3