2017-09-12 39 views
0

我在remarkjs幻燈片中添加了leafletjs地圖。如果包含地圖div的幻燈片在網頁初始加載時可見,則地圖工作正常。但是,如果帶地圖div的幻燈片不是可見幻燈片,則地圖div不可見,所以小冊子貼圖無法正常工作,因爲所有貼圖都未加載到div中。我想要做的就是在幻燈片中加載所有的地圖div,不管它們可能在哪個幻燈片上,然後當包含地圖的幻燈片出現時讓它們正確顯示。在隱形格創建lealetjs地圖

更新:建議的答案似乎應該回答我的問題,但我仍然卡住,不知道我是否在正確的軌道上。以下是更多細節。

由於我可以將許多地圖添加到幻燈片中,因此我使用地圖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

的可能的複製[數據切換標籤不下載單張地圖(https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-下載 - 傳單地圖) – ghybs

+0

似乎你的建議答案應該解決我的問題,但是,正如我更詳細地解釋,我不成功。 – punkish

+0

首先確保你的問題確實是由於在初始化時地圖大小不正確:如果在顯示地圖幻燈片後調整瀏覽器窗口大小,它是否突然生效? – ghybs

回答

0

leafletjs要求存在一個寬度和高度大於0px的div,即可見但不隱藏,以下載所需的地圖圖塊並顯示地圖。將地圖div添加到remarkjs幻燈片中意味着當啓動幻燈片時,這些div中的一個或多個將被隱藏。因此,leafletjs將無法​​在這些div中顯示地圖(隨機圖塊將丟失),直到瀏覽器調整大小,迫使leafletjs重新計算地圖div的大小並下載正確的圖塊。解決方法是在顯示帶有地圖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(); 
     } 
    } 
});