leaflet.js 阻止某些事件传播
leaflet.js stops certain events from propagating
我遇到了一个问题,我的 mouseenter
、mouseleave
、mouseover
和 mouseout
事件被吞没并且没有触发。
基本上我的页面上有一张地图,我在上面添加标记 (divIcons) 并绘制路径。与这张地图分开,我有一个工具提示和上下文菜单,它们附加到各种标记和路径上的事件以便被激活。地图对工具提示或上下文菜单一无所知,因此事件由使用 jquerys on
方法的配置文件附加。
假设 divIcons 具有 class markerElement
代码如下所示:
$(document).on('mouseenter', '.markerElement', function(){ console.log('ENTER'); });
$(document).on('mouseleave', '.markerElement', function(){ console.log('LEAVE'); });
我已经将问题追溯到 leaflet-src.js 版本 0.7.3 第 6484 行的 stopPropagation 方法。如果我注释掉 e.stopPropagation()
我的活动工作,我对这种方法与传单相关的目的有点困惑。
有没有其他方法可以让 mouseenter
和 mouseleave
事件附加到地图上动态创建的元素,而地图不知道它并且不更改传单源?
上下文菜单和工具提示代码适用于不在地图上的其他元素,因此可以根据某种选择器动态挑选元素的通用解决方案是理想的。
感谢任何想法
也许您可以选择禁用 L.Marker
和 L.Path
上的所有事件,您可以通过在它们的选项中使用 'clickable': false
来实现。
也可以通过创建从 L.Marker
扩展的自定义标记来仅禁用某些事件,这里我注释掉了 mouseover
和 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();
}
}
}
});
这里有一个关于 Plunker 的例子:http://plnkr.co/edit/naWEPz?p=preview
如果您想删除 L.Marker
的 clickevent 上的 stopPropagation,您也可以通过以类似方式扩展 L.Marker
来实现:
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
});
}
});
有点骇人听闻,但它应该有效,您可以对 L.Marker
中调用 stopPropagation
的其他方法执行相同的操作。 L.Path
也是如此,只需使用您想要更改的方法扩展它,我认为您可以开始(不知道如何正确测试,所以我没有 :D)祝你好运!
我遇到了一个问题,我的 mouseenter
、mouseleave
、mouseover
和 mouseout
事件被吞没并且没有触发。
基本上我的页面上有一张地图,我在上面添加标记 (divIcons) 并绘制路径。与这张地图分开,我有一个工具提示和上下文菜单,它们附加到各种标记和路径上的事件以便被激活。地图对工具提示或上下文菜单一无所知,因此事件由使用 jquerys on
方法的配置文件附加。
假设 divIcons 具有 class markerElement
代码如下所示:
$(document).on('mouseenter', '.markerElement', function(){ console.log('ENTER'); });
$(document).on('mouseleave', '.markerElement', function(){ console.log('LEAVE'); });
我已经将问题追溯到 leaflet-src.js 版本 0.7.3 第 6484 行的 stopPropagation 方法。如果我注释掉 e.stopPropagation()
我的活动工作,我对这种方法与传单相关的目的有点困惑。
有没有其他方法可以让 mouseenter
和 mouseleave
事件附加到地图上动态创建的元素,而地图不知道它并且不更改传单源?
上下文菜单和工具提示代码适用于不在地图上的其他元素,因此可以根据某种选择器动态挑选元素的通用解决方案是理想的。
感谢任何想法
也许您可以选择禁用 L.Marker
和 L.Path
上的所有事件,您可以通过在它们的选项中使用 'clickable': false
来实现。
也可以通过创建从 L.Marker
扩展的自定义标记来仅禁用某些事件,这里我注释掉了 mouseover
和 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();
}
}
}
});
这里有一个关于 Plunker 的例子:http://plnkr.co/edit/naWEPz?p=preview
如果您想删除 L.Marker
的 clickevent 上的 stopPropagation,您也可以通过以类似方式扩展 L.Marker
来实现:
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
});
}
});
有点骇人听闻,但它应该有效,您可以对 L.Marker
中调用 stopPropagation
的其他方法执行相同的操作。 L.Path
也是如此,只需使用您想要更改的方法扩展它,我认为您可以开始(不知道如何正确测试,所以我没有 :D)祝你好运!