在不可见的 div 中创建 lealetjs 地图
creating lealetjs map in an invisible div
我要在 remarkjs
幻灯片中添加 leafletjs
地图。如果包含地图 div 的幻灯片在网页初始加载时可见,则地图工作正常。但是,如果带有地图 div 的幻灯片不是可见幻灯片,则地图 div 是不可见的,因此传单地图无法正常工作,因为所有图块都未加载到 div.我想做的是将所有地图 div 加载到幻灯片中,无论它们在哪张幻灯片上,然后在包含地图的幻灯片出现时让它们正确显示。
更新: 建议的答案似乎应该回答我的问题,但我仍然卡住了,不确定我是否在正确的轨道上。以下是更多详细信息。
因为我可以在幻灯片中添加很多地图,所以我使用 class 地图名称 divs。
// 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()
正确触发并重新绘制地图。
leafletjs
需要 div 的宽度和高度 > 0px 存在,即可见,而不是隐藏,以下载所需的地图图块并显示地图。将地图 div 添加到 remarkjs
幻灯片意味着其中一个或多个 div 将在幻灯片启动时隐藏。因此,leafletjs
将无法在那些 div 中显示地图(随机图块将丢失),直到调整浏览器大小迫使 leafletjs
重新计算地图的大小 divs 并下载正确的图块。解决方案是在显示带有地图 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();
}
}
});
我要在 remarkjs
幻灯片中添加 leafletjs
地图。如果包含地图 div 的幻灯片在网页初始加载时可见,则地图工作正常。但是,如果带有地图 div 的幻灯片不是可见幻灯片,则地图 div 是不可见的,因此传单地图无法正常工作,因为所有图块都未加载到 div.我想做的是将所有地图 div 加载到幻灯片中,无论它们在哪张幻灯片上,然后在包含地图的幻灯片出现时让它们正确显示。
更新: 建议的答案似乎应该回答我的问题,但我仍然卡住了,不确定我是否在正确的轨道上。以下是更多详细信息。
因为我可以在幻灯片中添加很多地图,所以我使用 class 地图名称 divs。
// 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()
正确触发并重新绘制地图。
leafletjs
需要 div 的宽度和高度 > 0px 存在,即可见,而不是隐藏,以下载所需的地图图块并显示地图。将地图 div 添加到 remarkjs
幻灯片意味着其中一个或多个 div 将在幻灯片启动时隐藏。因此,leafletjs
将无法在那些 div 中显示地图(随机图块将丢失),直到调整浏览器大小迫使 leafletjs
重新计算地图的大小 divs 并下载正确的图块。解决方案是在显示带有地图 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();
}
}
});