Mapbox GL JS 画布在 Bootstrap 模式中无法正确显示

Gab*_*nes 5 javascript twitter-bootstrap mapbox bootstrap-modal mapbox-gl-js

根据Mapbox GL JS 快速入门指南,使用 Mapbox CDN 在网站上实现地图应该很简单。不幸的是,如果地图位于 Bootstrap 模态内部,则情况并非如此,该模态没有预定义宽度,该属性仅在模态打开后设置。

结果是加载默认宽度为 400px 的 Mapbox 画布,这可能与模态宽度不同并造成糟糕的用户体验。

此外,如果打开模式,然后调整浏览器窗口的大小,地图会自动按预期适合整个水平空间,这似乎是对调整大小事件的 JavaScript 响应。

下面是相关代码。

HTML 文件

<div id='map'></div>
Run Code Online (Sandbox Code Playgroud)

CSS文件

#map {
  height: 300px;
}
Run Code Online (Sandbox Code Playgroud)

JS文件

mapboxgl.accessToken = '...';
var map = new mapboxgl.Map({
    container: 'map',
    center: [..., ...],
    zoom: 10,
    style: 'mapbox://styles/mapbox/streets-v11'
});
Run Code Online (Sandbox Code Playgroud)

我尝试在 Bootstrap 3.4.0 模式中加载 Mapbox,就像我以前在使用 Google 地图或 Bing 地图时所做的那样,但在这两种情况下都嵌入在 iframe 中。因此,我期待看到 Mapbox 能够像 Google 地图和 Bing 地图一样填充整个模式。

相反,Mapbox 界面(左下角徽标和右下角信息按钮)正确定位在模式内部的边界处,但包含地图的画布定位不正确。

最后,为 #map CSS 属性设置预定义宽度并不是解决方案。如果宽度设置为固定宽度(以像素为单位),则可能无法在所有窗口尺寸上正确显示,而添加固定百分比宽度(例如 100%)则无法解决问题。

Gab*_*nes 6

Leaflet JavaScript 库的类似问题已经在此处此处得到解决。

事实证明,缺乏预定义的模式宽度使得 Mapbox 别无选择,只能首先加载默认宽度(在本例中为 400px)。由于打开模态框不会触发 Mapbox 可能正在侦听的任何事件(例如调整窗口大小),因此无论模态框显示后设置的大小如何,Mapbox 都会保持其默认宽度。

因此,要使 Mapbox 画布填充模态的整个宽度,必须将模态的打开(最终为其设置宽度)链接到 Mapbox resize 方法。

这里感兴趣的 Bootstrap 事件是"shown.bs.modal",一旦模态向用户显示并且 CSS 转换完成,就会触发该事件。这保证了模式的宽度已经被设置。

解决方案是在JS文件中的'map'变量定义后面添加以下代码:

$('#modalID').on('shown.bs.modal', function() {
    map.resize();
  });
Run Code Online (Sandbox Code Playgroud)

确保将“modalID”更改为用于标识相应模态的相同“id”。