Leaflet and Mapbox in modal not displaying properly

不想你离开。 提交于 2019-12-11 04:07:11

问题


Having a problem where Mapbox using Leaflet is not displaying correctly in a modal.

The map and marker are in the upper left and the rest of the tiles are blank.

I have tried the code directly in a page and not a modal and it works...

<style>
    #mapid { height: 300px; }
</style>
<div id="mapid"></div>
<script>
    var mymap = L.map('mapid').setView([<?= $return['latitude']; ?>, <?= $return['longitude']; ?>], 13);
    //var mymap  =  L.Map('mapid', { center: new L.LatLng(<?= $return['latitude']; ?>, <?= $return['longitude']; ?>]), zoom: 15, layers: [nexrad], zoomControl: true });
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=<?= $MapBoxToken ?>', {
        attribution: '&copy; <a href="http://mapbox.com">Mapbox</a>, &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>',
        maxZoom: 20,
        id: 'mapbox.streets',
        accessToken: '<?= $MapBoxToken ?>'
    }).addTo(mymap);    
    var marker = L.marker([<?= $return['latitude']; ?>, <?= $return['longitude']; ?>]).addTo(mymap);
</script>


回答1:


As explained in the linked post, having the map work when the browser window is resized is just a symptom of the issue. Leaflet listens to browser window resize event, and reads again the map viewport dimensions when it occurs, so that it can properly display tiles and center the view.

Under the hood, Leaflet simply calls map.invalidateSize() on the resize event.

So the proper solution for your case is NOT to have the browser window be resized, but to call map.invalidateSize().

And do that NOT after your map loads, but after your modal is opened, so that the map viewport now has its final dimensions.

Since you added the Bootstrap tag to your question, I guess your modal is built using Bootstrap. In that case, you can listen to the "shown.bs.modal" event:

var map = L.map('map').setView([48.86, 2.35], 11);

L.marker([48.86, 2.35]).addTo(map);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// Comment out the below code to see the difference.
$('#myModal').on('shown.bs.modal', function() {
  map.invalidateSize();
});
<!-- Bootstrap assets -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Launch demo modal that contains the map container.
</button>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">

        <!-- map container -->
        <div id="map" style="height: 180px"></div>

      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>



回答2:


The problem seem to with bootstap modal.

Needed to add map.invalidateSize(); but within "shown.bs.modal", as per ghybs suggestion.

$('#myModal').on('shown.bs.modal', function() {
  map.invalidateSize();
});

Note that the "map" in map.invalidateSize(); needs to be replace with the varable assigned in "var map = L.map()". In my original code in this post it was:

var mymap = L.map('mapid').setView([<?= $return['latitude']; ?>, <?= $return['longitude']; ?>], 13);

so I added:

$('#modalID').on('shown.bs.modal', function() {
  mymap.invalidateSize();
});


来源:https://stackoverflow.com/questions/49305901/leaflet-and-mapbox-in-modal-not-displaying-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!