【问题标题】:leaflet map does not appear correctly until resize在调整大小之前,传单地图无法正确显示
【发布时间】:2019-05-21 15:05:48
【问题描述】:

我在 Binding.scala 上使用带有 scalajs-leaflet 外观的 Leaflet,并且地图初始化/显示不正确。

为了重现该问题,我准备了一个类似于 scalajs-leaflet 中的 lihaoyi/workbench 页面。

首先,从https://github.com/mcku/scalajs-leaflet下载分叉的scalajs-leaflet

scalajs-leaflet 目录中运行sbt。 在 sbt 中输入~ example/fastOptJS。现在,一个 Web 服务器在 12345 端口启动。

打开 http://localhost:12345/example/target/scala-2.12/classes/leaflet2binding-dev.html 在浏览器中

问题是地图容器出现但内容(图块等)不正确。在窗口上调整大小后,地图变得很好,这会触发传单的 _onResize 处理程序。

容器位于Leaflet2Binding.scala 文件中,并且在初始化之前已经指定了它的大小:

val mapElement = <div id="mapid" style="width: 1000px; height: 600px;
                       position: relative; outline: currentcolor none medium;"
                    class="leaflet-container leaflet-touch leaflet-fade-anim 
                    leaflet-grab leaflet-touch-drag leaflet-touch-zoom"
                    data:tabindex="0"></div>.asInstanceOf[HTMLElement]

可以在返回元素之前在下一行插入一行lmap.invalidateSize(true) https://github.com/mcku/scalajs-leaflet/blob/83b770bc76de450567ababf6c7d2af0700dd58c9/example/src/main/scala/example/Leaflet2Binding.scala#L39,但在这种情况下没有帮助。即这里:

@dom def renderMap = {
  val mapElement = ... (same element as above)

  .. some other initializations ..

  lmap.invalidateSize(true) // true means, use animation

  println("mapElement._leaflet_id " +mapElement.asInstanceOf[js.Dynamic]._leaflet_id) // prints non-null value, makes me think the container is initialized

  mapElement
}

有什么想法吗?这是 binding.scala 特有的,但也可能是传单问题。

编辑可能的解决方法 看起来,地图元素的clientWidth 属性在此过程中不可用。这是可以理解的,因为文档还没有“准备好”。但是,css style.width 是可用的,并且可以在 px 中定义。在这种情况下,可以修补传单以在计算期间考虑 css 样式宽度。

如果样式宽度以 px 为单位指定,则它可以工作。

diff --git a/src/map/Map.js b/src/map/Map.js
index b94dd443..6544d7b7 100644
--- a/src/map/Map.js
+++ b/src/map/Map.js
@@ -903,8 +903,9 @@ export var Map = Evented.extend({
        getSize: function () {
                if (!this._size || this._sizeChanged) {
                    this._size = new Point(
-                               this._container.clientWidth || 0,
-                               this._container.clientHeight || 0);
+
+                               this._container.clientWidth || parseInt(this._container.style.width.replace("px",""),10) || 0,^M
+                               this._container.clientHeight || parseInt(this._container.style.height.replace("px",""),10) || 0);;^M

                        this._sizeChanged = false;
                }

【问题讨论】:

  • 这是 Leaflet 的一个已知且有据可查的问题。如果地图容器div 在地图初始化时没有定义的大小,则不会加载切片。如果由于配置中的某些动态而无法在页面加载时为地图容器指定大小,则可以在容器初始化后通过调用 map.invalidateSize() 来解决它。
  • @peeebeee 感谢 cmets。我已经更新了这个问题。是的,它与其他类似,但不是重复案例(请参阅编辑)。
  • invalidateSize(),而不是invalidateResize()
  • 是的,确实invalidateSize() 没有帮助。

标签: scala leaflet scala.js binding.scala


【解决方案1】:

可能lmap.invalidateSize(true) 调用得太早(DOM 未准备好或未重新绘制)。

确保不会发生这种情况。为了防止我把这段代码包装起来:

setTimeout(function () {
   mapid.invalidateSize(true);
}, 100);

这必须在每次 DOM 重绘后完成。

【讨论】:

  • 应该没有必要明确地等待 dom 解决并且元素的 id 是可查询的(因为绑定已经为我做了)。也因为我将元素作为参数传递给 L.map() 函数,而不是元素的 id。
猜你喜欢
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多