我在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()
正确地触发并重新绘制地图。
答案 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();
}
}
});