防止在 setView 之后在 Leaflet 中触发 moveend 事件
Prevent moveend event being fired in Leaflet after setView
我有一个简单的问题让我很困惑:
在 Leaflet 应用程序中,我有一个用于点击地图上的元素的事件侦听器:
marker.on('click', function () {
doStuff();
$('element').doStuff();
setView(this.getLatLng());
});
但是,setView 方法还会触发一个 'map moved' 事件,我不想触发该事件。使用普通 JavaScript 或 jQuery,我可以防止在点击事件函数内触发任何其他事件吗?
编辑:现在有了 Fiddle!要使用它,只需单击地图上的任意位置。如您所见,e.stopPropagation() 放在点击事件侦听器中时不起作用。
使用event.stopPropagation(), see the docs
marker.on('click', function (e) {
e.stopPropagation();
}
我不相信你能阻止 moveend
被解雇。 (注意:这些不是 jQuery 事件 - Leaflet 有自己的内部事件系统。)这是 setView
:
的来源
setView: function (center, zoom) {
zoom = zoom === undefined ? this.getZoom() : zoom;
this._resetView(L.latLng(center), this._limitZoom(zoom));
return this;
}
_resetView
总是在最后触发 moveend
:
_resetView: function (center, zoom, preserveMapOffset, afterZoomAnim) {
var zoomChanged = (this._zoom !== zoom);
if (!afterZoomAnim) {
this.fire('movestart');
if (zoomChanged) {
this.fire('zoomstart');
}
}
...
this.fire('moveend', {hard: !preserveMapOffset});
}
您可以调查自定义这些函数以允许抑制事件。
更新:
或者,您可以更改 moveend
事件处理程序。让它跟踪一个标志,当您不希望正常操作发生时设置该标志。
例如,您将设置类似于以下的处理程序:
map.on('moveend', myHandler);
让 myHandler
做类似的事情:
function myHandler(e) {
if (stopFlag) {
return;
}
else {
// Normal operation
...
}
}
然后只需启用和禁用 stopFlag
即可控制流量。这样做的好处是您不必在您的应用程序中发布自定义版本的 Leaflet。
开门见山:那永远行不通。通过使用 stopPropagation
/preventDefault
,您可以阻止 click
事件通过 dom 冒泡。没有其他的。一旦你执行 L.Map
的 setView
方法,它总是会触发 moveend
事件,它与 click
事件无关。它还会触发 movestart
和 move
事件,如果您还在 setView
中设置缩放级别,甚至会触发 resetview
事件。这就是 Leaflet 的工作方式。你总是可以扩展 L.Map
来编写你自己的逻辑,但我猜你最好为你的问题找到另一种解决方案。
这是我的更老套的解决方案。
开头
将 moveend 设置为 true
作为默认值。
var moveend = true;
点击事件内部
将 moveend 设置为 false
。
moveend = false;
map.setView(new L.LatLng(lat, lng));
移动结束事件
如果 moveend
是 true
,请执行某项操作。无论如何,将 moveend
设置为 true
以便下一个 运行。
map.on('moveend', (e) => {
if (moveend) {
// Do something if moveend is enabled
}
moveend = true;
});
我有一个简单的问题让我很困惑:
在 Leaflet 应用程序中,我有一个用于点击地图上的元素的事件侦听器:
marker.on('click', function () {
doStuff();
$('element').doStuff();
setView(this.getLatLng());
});
但是,setView 方法还会触发一个 'map moved' 事件,我不想触发该事件。使用普通 JavaScript 或 jQuery,我可以防止在点击事件函数内触发任何其他事件吗?
编辑:现在有了 Fiddle!要使用它,只需单击地图上的任意位置。如您所见,e.stopPropagation() 放在点击事件侦听器中时不起作用。
使用event.stopPropagation(), see the docs
marker.on('click', function (e) {
e.stopPropagation();
}
我不相信你能阻止 moveend
被解雇。 (注意:这些不是 jQuery 事件 - Leaflet 有自己的内部事件系统。)这是 setView
:
setView: function (center, zoom) {
zoom = zoom === undefined ? this.getZoom() : zoom;
this._resetView(L.latLng(center), this._limitZoom(zoom));
return this;
}
_resetView
总是在最后触发 moveend
:
_resetView: function (center, zoom, preserveMapOffset, afterZoomAnim) {
var zoomChanged = (this._zoom !== zoom);
if (!afterZoomAnim) {
this.fire('movestart');
if (zoomChanged) {
this.fire('zoomstart');
}
}
...
this.fire('moveend', {hard: !preserveMapOffset});
}
您可以调查自定义这些函数以允许抑制事件。
更新:
或者,您可以更改 moveend
事件处理程序。让它跟踪一个标志,当您不希望正常操作发生时设置该标志。
例如,您将设置类似于以下的处理程序:
map.on('moveend', myHandler);
让 myHandler
做类似的事情:
function myHandler(e) {
if (stopFlag) {
return;
}
else {
// Normal operation
...
}
}
然后只需启用和禁用 stopFlag
即可控制流量。这样做的好处是您不必在您的应用程序中发布自定义版本的 Leaflet。
开门见山:那永远行不通。通过使用 stopPropagation
/preventDefault
,您可以阻止 click
事件通过 dom 冒泡。没有其他的。一旦你执行 L.Map
的 setView
方法,它总是会触发 moveend
事件,它与 click
事件无关。它还会触发 movestart
和 move
事件,如果您还在 setView
中设置缩放级别,甚至会触发 resetview
事件。这就是 Leaflet 的工作方式。你总是可以扩展 L.Map
来编写你自己的逻辑,但我猜你最好为你的问题找到另一种解决方案。
这是我的更老套的解决方案。
开头
将 moveend 设置为 true
作为默认值。
var moveend = true;
点击事件内部
将 moveend 设置为 false
。
moveend = false;
map.setView(new L.LatLng(lat, lng));
移动结束事件
如果 moveend
是 true
,请执行某项操作。无论如何,将 moveend
设置为 true
以便下一个 运行。
map.on('moveend', (e) => {
if (moveend) {
// Do something if moveend is enabled
}
moveend = true;
});