0

我在幻灯片中添加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()正确触发和重新绘制地图。

4

1 回答 1

0

leafletjs需要存在宽度和高度> 0px 的 div,即可见,而不是隐藏,以下载所需的地图图块并显示地图。将地图 div 添加到remarkjs幻灯片意味着当幻灯片启动时这些 div 中的一个或多个将被隐藏。因此,在调整浏览器大小强制重新计算地图 div 的大小并下载正确的图块leafletjs之前,将无法在这些 div 中显示地图(随机图块会丢失) 。解决方案是在显示带有地图 div 的幻灯片时leafletjs触发该方法。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();
        }
    }
});
于 2017-09-12T14:17:44.900 回答