I am making a web app for different areas using Leaflet library. I have different Bootstrap tabs, each tab opens a new map of a new area.
The problem I am facing is that the tiles on the first tab load but the tiles on the second tab do not. Where am I wrong?
This is how I am loading my maps for now…
/* MAP LAYERS */
var map = L.map('mapid',{
zoomControl: true,
}).setView([24.2, 67.8], 9);
/* LOADING AND ADDING BASE MAPS */
var baseMap = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© <a href="https://carto.com/attributions">CARTO</a> contributors',
}).addTo(map);
/* MAP LAYERS */
var map1 = L.map('map_id',{
zoomControl: true,
}).setView([22.2, 63.8], 9);
/* LOADING AND ADDING BASE MAPS */
var baseMap = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© <a href="https://carto.com/attributions">CARTO</a> contributors',
}).addTo(map1);
My tabs:
<div id = "locations">
<ul class="nav nav-pills nav-fill" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="#tabA" data-toggle="pill" role="tab">I</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabB" data-toggle="pill">J</a>
</li>
</ul>
</div> <!-- End Tabs -->
The tab linkage:
<div class="tab-pane fade show active" id="tabA" role="tabpanel"> <!-- First Tab -->
<div class="col-6" id = 'map_grid'> <!-- Maps -->
<div id ="mapid"> </div> <!-- Div for the Maps -->
</div>
</div>
<div class="tab-pane fade" id="tabB" role="tabpanel"> <!-- Second Tab -->
<div class="col-6" id = 'map_grid'> <!-- Maps -->
<div id ="map_id"> </div> <!-- Div for the Maps -->
</div> <!-- End Maps -->
</div>
Best Answer
When Leaflet map is displayed in it's
<div>
element, map's size is calculated on the basis of the<div>
element size at the moment the map is added. If element is hidden, as it is the case of Boostrap tab above,<div>
element has no size and consequently map has no size when tab is displayed.Leaflet map has
invalidateSize()
method just for such cases. When this method is called, map's size is adjusted to the current size of it's<div>
element.All that is needed then is to catch the moment (event), when tab (HTML element) is displayed. One of the possible ways is to use
MutationObserver
DOM object to catch style changes in HTML element that holds the map.Below is quick simple example of that can be done.
CSS
HTML
JS