防止在 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() 放在点击事件侦听器中时不起作用。

http://jsfiddle.net/gc6e4jbg/

使用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.MapsetView 方法,它总是会触发 moveend 事件,它与 click 事件无关。它还会触发 movestartmove 事件,如果您还在 setView 中设置缩放级别,甚至会触发 resetview 事件。这就是 Leaflet 的工作方式。你总是可以扩展 L.Map 来编写你自己的逻辑,但我猜你最好为你的问题找到另一种解决方案。

这是我的更老套的解决方案。

开头

将 moveend 设置为 true 作为默认值。

var moveend = true;

点击事件内部

将 moveend 设置为 false

moveend = false;
map.setView(new L.LatLng(lat, lng));

移动结束事件

如果 moveendtrue,请执行某项操作。无论如何,将 moveend 设置为 true 以便下一个 运行。

map.on('moveend', (e) => {
  if (moveend) {
    // Do something if moveend is enabled
  }
  moveend = true;
});