单击缩放按钮时如何防止传单滚动页面?

Nic*_* K9 5 javascript zooming leaflet

我在 HTML 页面上有一张传单地图。当页面滚动以使地图的任何部分都在视口之外并且我单击缩放按钮时,地图会跳转以使其在视口中完全可见。如果整个地图不适合,那么地图的顶部将与视口的顶部对齐,而底部只是悬在末端。

这很烦人,因为用户刚刚按下的缩放按钮不再位于光标下,他们必须再次找到它。

我已经尝试了内置缩放栏和我使用的自定义缩放栏,map.setZoom()并且行为是一致的。但是,https: //leafletjs.com 上的示例地图没有这样做,所以我不知所措。

我的地图很简单:

var home = {center: L.LatLng(51.499725, -0.124695), zoom: 11};
var mymap = L.map('map').setView(home.center, home.zoom);
Run Code Online (Sandbox Code Playgroud)

这个问题听起来与我所看到的相似,但比我的情况更复杂。无论如何,没有解决方案。

编辑:这是 html 和 CSS,但它不能更基本。

地图.html

    <div class="container mx-sm-3">
        <div class="row">
            <div class="col">
                <div id="map"></div>
            </div>
        </div>
    </div>
Run Code Online (Sandbox Code Playgroud)

地图.css

#map {
    height: 570px;
    width: 700px;
}
Run Code Online (Sandbox Code Playgroud)

Iva*_*hez 7

罪魁祸首是这行代码

this._map.getContainer().focus();
Run Code Online (Sandbox Code Playgroud)

这背后的原因是什么?地图容器必须具有焦点,以便通过它路由键盘事件。单击缩放按钮会将焦点设置在按钮本身上,并在某些情况下使地图行为异常。

但是焦点的一个副作用是聚焦 HTML 元素会使用户代理(Web 浏览器)将其滚动到视图中,因为假设用户在对它进行任何键盘输入之前希望看到聚焦的元素。

有了这些知识,我将以两种不同的方式重新表述您的问题:

我根本不需要聚焦地图元素。单击缩放按钮后,如何防止 Leaflet 聚焦地图?

通过使_refocusOnMap()私有方法L.Control什么都不做。

这可以通过猴子补丁来快速&肮脏的方式完成:

L.Control.prototype._refocusOnMap = function _refocusOnMap() {};
Run Code Online (Sandbox Code Playgroud)

请记住在实例化地图之前进行猴子补丁。“干净”将创建子类L.Control和/或L.Control.Zoom基于此。如果您有自己的缩放控件,您还可以提供一种自定义_refocusOnMap方法,而不是依赖父类提供的方法。

我希望键盘控件继续工作,但我不想在按下缩放按钮后将整个地图滚动到视图中。可以聚焦地图但跳过“滚动到视图”业务吗?

是的,有警告。

focus方法HTMLElements接受一个options可以保存preventScroll选项的参数。

因此,您可以_refocusOnMap()通过以下方式进行猴子补丁:

L.Control.prototype._refocusOnMap = function _refocusOnMap(ev) {
    // if map exists and event is not a keyboard event
    if (this._map && ev && ev.screenX > 0 && ev.screenY > 0) {
        this._map.getContainer().focus({ preventScroll: true });
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,但是,这对于支持preventScroll不存在于所有的浏览器

另一种方法是preventDefault要么focusfocusin在地图上的活动,喜欢的东西:

L.DomEvent.on(map.getContainer(), 'focus', L.DomEvent.preventDefault)
Run Code Online (Sandbox Code Playgroud)

但是,由于 Web 浏览器之间的不一致,这可能不仅会停止滚动而且会停止聚焦,或者可能根本没有效果,具体取决于所使用的 Web 浏览器。

  • 仅供参考,这在 [Leaflet #4125](https://github.com/Leaflet/Leaflet/issues/4125) 中进行了跟踪。 (2认同)

小智 5

    this._map.getContainer().focus = ()=>{}
Run Code Online (Sandbox Code Playgroud)

  • 德罗克,谢谢你的回答。请为您的答案提供更多上下文,而不仅仅是代码。 (2认同)