移动端Leaflet地图上层Bootstrap模态框滚动显示bug求助
问题:Vue2+Leaflet+Bootstrap模态框滚动导致地图空白
- 在移动端Chrome或三星浏览器中,滚动Bootstrap模态框时,浏览器导航栏自动隐藏,页面显示高度增加,Leaflet地图下方出现空白区域
- 尝试调用
map.invalidateSize()无效;修改模态框CSS后,Safari中模态框完全无法滚动
解决方案
核心思路是锁定页面视口高度,避免导航栏隐藏触发的高度变化,同时保证模态框在各浏览器的滚动兼容性:
- 模态框显示时,给
html和body添加固定高度样式,阻止视口尺寸突变 - 仅让
modal-body负责滚动,而非整个modal-dialog,解决Safari滚动失效问题 - 模态框关闭后移除固定样式,并延迟调用地图尺寸校验,确保DOM更新完成
修改后的完整代码
Template部分
<template> <div id="app"> <l-map ref="map" :center="[51, 0]" :zoom="10" @ready="onReady()"> <l-tile-layer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"/> <l-circle-marker :lat-lng="[51, 0]" @click="showModal()"/> </l-map> <div ref="testModal" class="modal fade" id="testModal" tabindex="-1" aria-labelledby="poi" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Test</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body custom-modal-body"> <p v-for="n in 30" :key="n">line {{n}}</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> </div> </template>
Script部分
import { Modal } from 'bootstrap'; import { LMap, LTileLayer, LCircleMarker } from 'vue2-leaflet'; export default { name: 'App', components: { LMap, LTileLayer, LCircleMarker, }, data() { return { testModal: null, mapInstance: null } }, methods: { onReady() { this.mapInstance = this.$refs.map.mapObject; const modalEl = document.getElementById('testModal'); // 模态框显示时锁定视口 modalEl.addEventListener('show.bs.modal', () => { document.documentElement.classList.add('modal-open-fixed'); document.body.classList.add('modal-open-fixed'); }); // 模态框关闭后恢复视口并校验地图尺寸 modalEl.addEventListener('hidden.bs.modal', () => { document.documentElement.classList.remove('modal-open-fixed'); document.body.classList.remove('modal-open-fixed'); // 延迟调用确保DOM已更新 setTimeout(() => { this.mapInstance.invalidateSize(); }, 100); }); }, showModal() { this.testModal.show(); } }, mounted() { this.testModal = new Modal(document.getElementById('testModal')); } }
Style部分
html, body, #app { height: 100%; margin: 0; padding: 0; } /* 锁定视口高度,防止导航栏隐藏触发高度变化 */ .modal-open-fixed { height: 100vh; overflow: hidden; position: fixed; width: 100%; } /* 仅让modal-body滚动,保证Safari兼容性 */ .custom-modal-body { max-height: calc(100vh - 140px); /* 减去header和footer高度 */ overflow-y: auto; } /* 引入Bootstrap样式 */ @import '~bootstrap/scss/bootstrap.scss';
关键说明
modal-open-fixed类通过固定视口高度,彻底避免浏览器导航栏隐藏导致的页面高度突变- 滚动区域限定在
modal-body,符合Bootstrap原生滚动逻辑,解决Safari滚动失效问题 - 延迟调用
invalidateSize()确保模态框关闭后DOM已完全恢复,地图能正确计算容器尺寸
内容的提问来源于stack exchange,提问作者gregoire
相关产品推荐
相关产品推荐

