在一个看不见的div中创建lealetjs地图

时间:2017-09-12 07:17:23

标签: leaflet remarkjs

我在leafletjs幻灯片中添加了remarkjs地图。如果在初始加载网页时包含地图div的幻灯片可见,则地图可以正常工作。但是,如果带有地图div的幻灯片不是可见幻灯片,则地图div是不可见的,因此传单地图无法正常工作,因为所有切片都未加载到div中。我想要做的是在幻灯片中加载所有地图div,无论它们在哪个幻灯片上,然后在包含地图的幻灯片出现时正确显示它们。

更新:建议的答案似乎应该回答我的问题,但我仍然感到困惑,不确定我是否在正确的轨道上。以下是更多细节。

由于我可以在幻灯片中添加许多地图,因此我使用地图div的类名。

// css
.map { width: 100vh; height: 100vh; }

// html
<div class="map" data-lat="47" data-lon="106"></div>
<div class="map" data-lat="0" data-lon="0"></div>
<!-- possibly on a different slide -->
<div class="map" data-lat="30" data-lon="28"></div>

// js
var maps = []; // for storing map elements
var mapDivs = document.getElementsByClassName('map');

for (var i=0, j=mapDivs.length; i<j; i++) {
    var map = L.map(mapDivs[i]).setView(
        [mapDivs[i].dataset.lat, mapDivs[i].dataset.lon], 
        13
    );

    // store map for later
    maps.push(map);
    L.tileLayer(…).addTo(map);
}

slideshow.on('showSlide', function (slide) {
    for (var i=0, j=maps.length; i<j; i++) {
        maps[i].invalidateSize();
    }
});

我的逻辑说上面应该有效,但事实并非如此。我做错了什么?

Update2: map.invalidateSize()答案确实是解决方案的一部分。我的错是我打电话给slideshow.on('showSlide', fn),但我应该一直打电话给slideshow.on('afterShowSlide', fn)。后者为remarkjs提供了实际创建当前幻灯片的机会,该幻灯片可能具有地图div,从而允许map.invalidateSize()正确地触发并重新绘制地图。

1 个答案:

答案 0 :(得分:0)

leafletjs需要宽度和高度的div> 0px存在,即可见,而不是隐藏,以下载所需的地图图块并显示地图。将地图div添加到remarkjs幻灯片放映意味着在启动幻灯片放映时将隐藏这些div中的一个或多个。因此,leafletjs将无法在这些div中显示地图(随机图块将丢失),直到调整浏览器大小,迫使leafletjs重新计算地图div的大小并下载正确的图块。解决方案是在显示带有map div的幻灯片时触发map.invalidateSize()方法。这是我最后的表现

/* css ******************************/
.map { width: 100vh; height: 100vh; }


<!---------------------------------------------
html
map divs possibly on different slides, with a
`map: true` property on each slide with a map
----------------------------------------------->

---
map: true
<div class="map" data-lat="47" data-lon="106"></div>
---
map: true
<div class="map" data-lat="0" data-lon="0"></div>
---
map: true
<div class="map" data-lat="30" data-lon="28"></div>

// js /////////////////////////////////////////
var maps = []; // for storing leaflet map elements
var mapDivs = document.getElementsByClassName('map');

for (var i=0, j=mapDivs.length; i<j; i++) {

    // store map for later
    maps.push(L.map(mapDivs[i]).setView(
        [mapDivs[i].dataset.lat, mapDivs[i].dataset.lon], 
        zoomLevel
    ));

    // add map to the tileLayer
    L.tileLayer(…).addTo(maps[i]);
}

// use the 'afterShowSlide' event to ensure the 
// map div has been created
slideshow.on('afterShowSlide', function (slide) {

    // only if the slide has a 'map' property
    if (slide.properties.map) {
        for (var i=0, j=maps.length; i<j; i++) {
            maps[i].invalidateSize();
        }
    }
});