在容器调整大小时调整传单地图的大小

Posted

技术标签:

【中文标题】在容器调整大小时调整传单地图的大小【英文标题】:Resizing a leaflet map on container resize 【发布时间】:2014-08-16 05:34:25 【问题描述】:

我有一个包含传单地图的<div>。在某些事件中,<div> 的高度将会改变。我想让地图调整到其周围<div> 的新尺寸,以便旧中心在调整后的更小或更大的地图中居中。我尝试使用invalidateSize() 函数,但它似乎根本不起作用。在map-container-resize 事件之后如何调整地图大小和居中?

$mapContainer.on('map-container-resize', function () 
   map.invalidateSize(); // doesn't seem to do anything
);

编辑以提供更多上下文:

地图容器最初的样式为

#map-container 
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;

    transition: height 0.5s ease-in-out;

用户单击某个按钮后,页面底部会显示另一个面板,并且地图容器的高度将降低到小于 100%(例如 80%)。

单击此按钮后,将触发 map-container-resize 事件,以便我可以使地图调整大小并以旧的(即在调整大小之前)中心为中心。然后,地图本身也应调整为其初始高度的 80%。

invalidateSize 的 APi 文档似乎是我想要的:

"检查地图容器大小是否改变,如果改变则更新地图 [...]”

但是看看在调用 invalidateSize 前后 getSize 函数的输出,没有什么不同,地图保持原来的大小。

【问题讨论】:

这需要更多上下文。您实际上是在触发map-container-resize 事件吗?地图在 CSS 中的大小如何? 您的意思是“调整大小”事件吗?这个有效 on('resize') 仅适用于 WINDOW 调整大小,map-container-resize 不存在。那么这里的实际事件是什么? 【参考方案1】:

您可以在 resize 之后使用以下代码

map.invalidateSize()

https://github.com/Leaflet/Leaflet/issues/690

【讨论】:

【参考方案2】:

只需调用调整窗口大小事件,而不是定时加载地图。

L.tileLayer('https://s.tile.openstreetmap.org/z/x/y.png').addTo(map);

window.dispatchEvent(new Event('resize'));  


// Triggers a window resize 
// Thus your map automatically triggers invalidateSize().

【讨论】:

这个解决方案真的很干净,到目前为止对我来说效果很好,这种方法有什么缺点吗? 是的。如果您想在主应用程序级别检测真正的窗口调整大小事件,请说以后。上述过程将产生一个错误信号。那是在启动期间或取决于您调用上述过程的次数。【参考方案3】:

我今天遇到了这个问题,想根据 2020 Browser API 提供一个更新的答案。此示例使用浏览器的ResizeObserver 来监控也安装了 Leaflet 的 div 的大小。假设以下 html 片段:

<div id="map" />

使用以下 javascript

const mapDiv = document.getElementById("map");
const map = L.map(mapDiv).setView([51.505, -0.09], 13);
L.tileLayer('https://s.tile.openstreetmap.org/z/x/y.png').addTo(map);

const resizeObserver = new ResizeObserver(() => 
  map.invalidateSize();
);

resizeObserver.observe(mapDiv);

这应该监控地图 div,并在地图 div 大小发生变化时调用 Leaflet 地图上的 invalidateSize() 方法。这种方法允许您处理“更接近”地图代码的大小调整,而不是尝试依赖窗口大小调整事件或侦听应用程序中其他地方触发的更改。

显然,地图 div 本身的 CSS 需要确保它以任何您想要的方式调整大小。这段代码 sn-p 将确保 Leaflet 在发生这种情况时得到适当的更新。

【讨论】:

这个答案对 Angular 8 或更高版本的某些版本非常有帮助 const resizeObserver = new (window as any).ResizeObserver(() => map.invalidateSize(); ); resizeObserver.observe(mapDiv);【参考方案4】:

在运行 VueJS,Leaflet 1.2.0 时遇到了这个问题。调整大小并没有像上面提到的其他人那样完成。我在 VueJS 中的解决方案是调用 nextTick 函数:

  var vm = this
  var container = vm.$refs.container
  vm.mapStyle.width = `$vm.getElementContentWidth(container)px`
  vm.mapStyle.height = `$vm.getElementContentHeight(container)px`
  vm.$nextTick(() => 
    if (vm.map) vm.map.invalidateSize()
    if (vm.layerBase) vm.layerBase.redraw()
  )

我相信纯 javascript 会是

【讨论】:

感谢带有 invalidateSize 的 nextTick 解决了我的问题!【参考方案5】:

接受的答案有点老套,因为它依赖于睡眠时间比转换时间长。

我发现this 运行良好:

$("body").on($.support.transition.end, '#main-navbar .nav-collapse', function(event)    
    console.log("end of the animation");
);

【讨论】:

请注意jQuery.support is deprecated。【参考方案6】:

问题在于 #map-container div 的大小调整是通过 css 转换完成的。转换尚未开始,更不用说结束了,当调用 invalidateSize 时,传单地图无法识别其周围div 的任何尺寸变化。

延迟触发map-container-resize 事件解决了这个问题。这样:

setTimeout(function() map.invalidateSize(), 400);

【讨论】:

工作示例:https://***.com/a/29787856/2471632 更好的解决方案可能是收听the transitionend event。【参考方案7】:

L.Map.invalidateSize() 仅通知传单地图对象其容器大小已更改,因此应该绘制更少或更多的地图图块。它实际上并没有改变任何尺寸,例如它包含&lt;div&gt;,并且不移动地图。你应该自己做。

【讨论】:

这应该是最好的答案!谢谢 它确实会移动地图

以上是关于在容器调整大小时调整传单地图的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在包含地图容器的 div 中附加谷歌地图的调整大小方法?

在窗口调整大小时调整图像地图大小

调整 div 大小时无法让 Google 地图高度自动调整大小

让用户调整 div 容器的大小,页面刷新后保存

jQuery动态比例元素/图像调整大小

在容器 Kendo 窗口调整大小时动态更改 Kendo Grid 行的高度