You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bootstrap模态框中Leaflet地图瓦片点击后无法完全加载问题求助

Bootstrap模态框中Leaflet地图瓦片加载不全的解决方案

问题现象

点击按钮打开Bootstrap模态框时,Leaflet地图的瓦片无法完全加载,仅部分区域显示地图内容。

问题代码

HTML代码

<button class="btn btn-success pull-left" onClick="return map()"><i class="fa fa-map-marker"></i> openMap</button>
<div class="modal fade" id="mapModal">
    <div class="container">
        <div class="modal-dialog modal-lg">
            <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="address-label">modal title</h4>
                </div>
                <div class="modal-body">
                    <div id="map"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-success pull-left" data-dismiss="modal" onclick="return map()">add</button>
                </div>
            </div>
        </div>
    </div>
</div>

JavaScript代码

function map(){
$('#mapModal').modal();
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        });
        var map = L.map('map', {
            center: [35.7219, 51.3347],
            zoom: 10,
            layers: [osm]
        });
}

问题原因

模态框初始化时处于隐藏状态,Leaflet无法正确获取地图容器的实际尺寸,导致瓦片加载时计算的显示区域错误,出现加载不全的情况。

修复方案

核心思路

  1. 等待模态框完全显示后再初始化地图,此时容器尺寸已确定。
  2. 避免重复创建地图实例,提升性能。
  3. 给地图容器设置固定高度,确保显示空间充足。

修改后的代码

1. 调整HTML(给地图容器添加尺寸样式)

<div class="modal-body">
    <!-- 设置地图容器固定高度和宽度 -->
    <div id="map" style="height: 400px; width: 100%;"></div>
</div>

2. 重构JavaScript代码

// 全局变量存储地图实例,避免重复创建
let mapInstance = null;

function map() {
    // 仅触发模态框显示
    $('#mapModal').modal();
}

// 监听模态框完全显示事件
$('#mapModal').on('shown.bs.modal', function () {
    if (!mapInstance) {
        // 首次打开模态框时初始化地图
        const osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        });
        mapInstance = L.map('map', {
            center: [35.7219, 51.3347],
            zoom: 10,
            layers: [osm]
        });
    } else {
        // 非首次打开,触发地图尺寸重绘
        mapInstance.invalidateSize();
    }
});

代码说明

  • shown.bs.modal:Bootstrap模态框的内置事件,在模态框完全显示(动画结束)后触发,此时地图容器的尺寸已稳定。
  • mapInstance:全局变量存储地图实例,避免每次打开模态框都重新创建地图,减少资源消耗。
  • invalidateSize():Leaflet提供的方法,强制地图重新计算容器尺寸并适配,解决再次打开模态框时可能出现的瓦片偏移问题。

内容的提问来源于stack exchange,提问作者AliReza Abbasian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:20:33