Javascript 灰色框出现在模态框中嵌入的谷歌地图的部分中

Javascript 灰色框出现在模态框中嵌入的谷歌地图的部分中,javascript,google-maps,google-maps-api-3,modal-dialog,Javascript,Google Maps,Google Maps Api 3,Modal Dialog,我在通过V3API将Google地图嵌入模式框时遇到了一个问题 显示模式时,地图画布中会出现灰色框。调整浏览器窗口的大小、打开Web Inspector等会使所有地图平铺可见,即“强制重新渲染”地图 map元素的父元素(部分#map modal,请参见下面的代码)在其CSS on page load中设置了display:none。单击“显示”按钮时,JS模式代码会自动设置display:block。如果我临时从modal元素中删除display:none,则在页面刷新时映射将正确呈现。谷歌地图

我在通过V3API将Google地图嵌入模式框时遇到了一个问题

显示模式时,地图画布中会出现灰色框。调整浏览器窗口的大小、打开Web Inspector等会使所有地图平铺可见,即“强制重新渲染”地图

map元素的父元素(
部分#map modal
,请参见下面的代码)在其CSS on page load中设置了
display:none
。单击“显示”按钮时,JS模式代码会自动设置
display:block
。如果我临时从modal元素中删除
display:none
,则在页面刷新时映射将正确呈现。谷歌地图不喜欢有一个隐藏的父元素吗

我正在使用Twitter的引导模式jQuery插件,并用CSS控制模式本身。它是固定定位的,有一个像素宽度,等等。没有什么不寻常的

当然,我在谷歌上搜索了很多解决方案,并指出了触发
resize
事件的Google API方法:

google.maps.event.trigger(map, 'resize');
我确实这样做了,但没有用

相关代码:

如你所见,我将在第39行触发事件

(按侧边栏底部的“查看较大地图”按钮)

档案:

  • fagerhult.js
  • fagerhult.map.js
  • bootstrap modal.js
  • master.css

我将非常感谢任何帮助或额外的眼睛在这方面,因为我很快就会疯了

就我在Chrome上使用JS live edit稍微戳了戳,延迟执行
resize
以等待模态动画可能会工作:)


我发现在地图的父元素(模态)上有
display:none
真的把事情搞砸了。我把它改成了“可见性:隐藏”,只是迫不及待地想看看会发生什么,结果它成功了


我还修改了模态JS代码,将模态设置为显示/隐藏时的可见性:可见/隐藏。否则,它将再次设置显示:无/块,这将再次创建灰色框。

问题是,如果您这样做:

$("#mapModalLink").click(function(){
  google.maps.event.trigger(map,"resize");
});
在触发调整大小事件时,您的模式可能未打开(并以正确的大小显示)。要解决这个问题:

$("#mapModalLink").click(function(){
  $("#mapModal").show();
  google.maps.event.trigger(map, 'resize');
});

至少对我有用:)

我的bootstrap-modal.js v 2.0解决方案

在Modal div中将“隐藏”类替换为“不可见”

<div id="map_modal" class="modal fade invisible">
...
</div>
链接html

<a href="javascript:open_map()">Open map</a>

尝试使用模式事件处理程序。我认为这是最简洁(也是最正确)的方法,可以确保在显示模式后调整大小,而无需重写任何插件:

$('#map-modal').on('shown', function () {
  google.maps.event.trigger(map, 'resize');
})
更新:我刚刚意识到这个解决方案仍然不能正确地将地图居中,所以我需要再添加一个命令:

$('#map-modal').on('shown', function () {
  google.maps.event.trigger(map, 'resize');
  map.setCenter(new google.maps.LatLng(42.3605336, -72.6362989));
})

我遇到了这个问题,通过回调draw方法解决了这个问题。我认为这是因为绘制地图比显示对话框更容易

我用这个代码来解决它(它不是一个模态窗口):


对于那些使用bootstrap的人,我必须从我的“modal”类中删除“fade”

从未接到过电话。这个问题似乎让我想到了消除褪色。


这不是一个最佳的解决方案,因为淡入淡出实际上非常好,可以在不调整大小的情况下成功渲染…

贴图

为什么调整大小会给你正确的地图

因为浏览器再次绘制视图

如何修复它

要在最近触发的任何面板中获得地图的正确布局,必须在加载面板后绘制地图。这可以通过(setTimeout)代码实现,如下所述。 代码目标是在60毫秒后触发映射调整大小事件

setTimeout(function () {
        uiGmapIsReady.promise().then(function (maps) {
            google.maps.event.trigger(maps[0].map, 'resize');
            lat = -37;
            lon = 144;
            maps[0].map.panTo(new google.maps.LatLng(lat,lon));
            var marker = {
                id: Date.now(),
                coords: {
                    latitude: lat,
                    longitude: lon
                }
            };
            $scope.map.markers = [];
            $scope.map.markers.push(marker);
            console.log($scope.map.markers);
        });
    }, 60);

关于这个主题的其他StackOverflow文章我已经试过了:--谷歌地图v3 API:如果你面临同样的问题,试试这个:哦。。。非常感谢你,约翰,我花了很长时间试图解决这个问题。工作得很有魅力。谢谢。修改模态js是一个非常糟糕的解决方案。这个问题的最佳和正确的解决方案。这应该被标记为答案。
$('#map').show(function()
{
    var punto = new google.maps.LatLng(this.latitud, this.longitud);
    var myOptions = {zoom: 15, center: punto, mapTypeId: google.maps.MapTypeId.ROADMAP,mapTypeControl:false, draggable:false};
    var map = new google.maps.Map(document.getElementById('mapa'),  myOptions);
    var marker = new google.maps.Marker({
    position:punto,
    map: map,
    title: this.nombre
});
});
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
     google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
          google.maps.event.trigger(map, 'resize');

     });
});
<div class="modal fade" 
<div class="modal" ...
.on("shown.bs.modal" ...
setTimeout(function () {
        uiGmapIsReady.promise().then(function (maps) {
            google.maps.event.trigger(maps[0].map, 'resize');
            lat = -37;
            lon = 144;
            maps[0].map.panTo(new google.maps.LatLng(lat,lon));
            var marker = {
                id: Date.now(),
                coords: {
                    latitude: lat,
                    longitude: lon
                }
            };
            $scope.map.markers = [];
            $scope.map.markers.push(marker);
            console.log($scope.map.markers);
        });
    }, 60);