如何在隐藏元素中加载Google地图

127

我的页面中有一个嵌套在隐藏的 div 中的 Google 地图。我点击链接后显示该 div,但是只有地图的左上角显示出来。

我尝试在点击后运行如下代码:

map0.onResize();
或者:
google.maps.event.trigger(map0, 'resize')

我该怎么做?

这是一个显示了隐藏地图的div后所看到的图片:

Alt text


@Matt Ball - 我已经让它工作了。在创建谷歌地图对象后,我将其存储在全局变量中,以便稍后可以引用它,并且现在调用resize似乎起作用了。我正在尝试避免每次显示地图时都重新创建地图对象,因为我允许人们来回切换。 - leora
@ooo,使用下面的代码非常简单。你只需要添加一个if条件来检查地图对象是否已经初始化即可。这是一个即兴编写的代码,旨在解决您最初的问题,即正确加载地图。 - Philar
@philar - 是的,谢谢你。这样我就可以点赞了 :). 无论如何,我需要将变量存储在全局级别,以避免重新初始化。 - leora
在下面的代码中,由于未在“初始化”函数内声明,所以map对象隐式成为全局变量。 - Philar
23个回答

126

我遇到了相同的问题,并发现当显示div时,调用google.maps.event.trigger(map, 'resize');似乎解决了我的问题。


64
为了在调整大小后保持地图的原始中心,可以考虑通过以下方式扩展调整大小语句: var center = map.getCenter(); google.maps.event.trigger(map, 'resize'); map.setCenter(center); - John Doppelmann
10
不确定为什么,但我需要用小的setTimeout包装解决方案才能使其正常工作:setTimeout(function() {google.maps.event.trigger(map, 'resize')}, 100); - HoffZ
@JohnDoppelmann 感谢您的提示!我之前并不知道为什么它无法保持居中,也不知道如何强制使其回到居中状态。 - Noah Duncan
在触发“resize”事件后再次设置地图中心和缩放级别。更多信息请参见:https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448 - ruhong
@HoffZ,这可能是由于您的调整大小代码在显示效果之前触发,超时会延迟其执行,然后调整大小可以发挥作用。您可能可以通过改变代码执行顺序来实现相同的效果,确保在触发事件时,div的显示在地图调整大小之前执行。 - Bardo

103

我刚刚亲自测试了一下,以下是我的做法。这很简单明了。

HTML

<div id="map_canvas" style="width:700px; height:500px; margin-left:80px;" ></div>
<button onclick="displayMap()">Show Map</button>

CSS

<style type="text/css">
    #map_canvas {display: none;}
</style>

JavaScript

<script>
    function displayMap()
    {
        document.getElementById( 'map_canvas' ).style.display = "block";
        initialize();
    }

    function initialize()
    {
        // Create the map
        var myOptions = {
            zoom: 14,
            center: new google.maps.LatLng( 0.0, 0.0 ),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        map = new google.maps.Map( document.getElementById( "map_canvas" ), myOptions );
    }
</script>

所以基本上只有在显示div时才实例化地图?有没有办法使地图对象仅在页面加载时实例化一次? - lucas
1
如果你正在调用show()函数并且需要时间来调整大小,我建议你使用setTimeout延迟来调用第二个函数。 - Eric.18

26

使用:

google.maps.event.trigger($("#div_ID")[0], 'resize');

如果您没有可用的变量映射,它应该是包含GMAP的

中的第一个元素(除非您做了一些愚蠢的事情)。


你确定可以在 div 上触发元素,而不是 google.map.Map 对象吗? - Salman A
@SalmanA - 我刚刚检查了一下,对我有效(尽管地图似乎有一个新的中心)。从以前的研究中,我也不知道这是可能的,所以向 CSN 致敬。 - Hal
1
C S N... 这对我有效,但是它将中心位置留在了错误的位置。我的地图像 OP 的屏幕截图一样初始化,而且就好像 center: 是以我的 map_canvas 左上角为中心。有什么想法可以让它绘制在中心位置? - Kirk Ross

13

我在Bootstrap选项卡中嵌入了一个Google地图,但它显示不正确。这是我的解决方法。

// Previously stored my map object(s) in googleMaps array

$('a[href="#profileTab"]').on('shown', function() {   // When tab is displayed...
    var map = googleMaps[0],
        center = map.getCenter();
    google.maps.event.trigger(map, 'resize');         // fixes map display
    map.setCenter(center);                            // centers map correctly
});

1
我不得不将“shown”替换为“shown.bs.tab”,才能使一个隐藏在非活动选项卡中的地图正常工作。谢谢。 - Nicola
我正在使用SmartWizard 4,这是唯一有效的解决方案,而且效果非常好!我将'a[href="#profileTab"]'更改为step-2,它是包含地图DIV的DIV的名称。 - GeospatialPython.com

7

如何在改变 div 大小时刷新地图

仅仅调用 google.maps.event.trigger(map, 'resize'); 是不够的。您还应该重设地图的中心。

var map;

var initialize= function (){
    ...
}

var resize = function () {
    if (typeof(map) == "undefined") {) {
        // initialize the map. You only need this if you may not have initialized your map when resize() is called.
        initialize();
    } else {
        // okay, we've got a map and we need to resize it
        var center = map.getCenter();
        google.maps.event.trigger(map, 'resize');
        map.setCenter(center);
    }
}

如何监听 resize 事件

Angular (ng-show 或 ui-bootstrap 折叠组件)

直接绑定元素的可见性,而不是绑定到 ng-show 的值,因为 $watch 可能会在 ng-show 更新之前触发(导致 div 仍然是不可见的)。

scope.$watch(function () { return element.is(':visible'); },
    function () {
        resize();
    }
);

jQuery .show()

使用内置的回调函数

$("#myMapDiv").show(speed, function() { resize(); });

Bootstrap 3 模态框

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

你的bootstrap 3模态框调整方法完美地解决了我的问题,而大部分其他建议都没有。谢谢! - BrianLegg

7

还有一种方法是直接触发本地窗口大小调整事件。

Google Maps 将自动重新加载:

window.dispatchEvent(new Event('resize'));

6
如果您通过复制/粘贴iframe代码插入了Google Maps地图,并且不想使用Google Maps API,那么这是一个简单的解决方案。只需在显示隐藏地图时执行以下JavaScript代码行即可。它只需要iframe HTML代码并将其插入到相同的位置,以便再次呈现:
document.getElementById("map-wrapper").innerHTML = document.getElementById("map-wrapper").innerHTML;

jQuery版本:

$('#map-wrapper').html( $('#map-wrapper').html() );

HTML:

<!-- .... -->
<div id="map-wrapper"><iframe src="https://www.google.com/maps/..." /></div>
<!-- .... -->

以下示例适用于最初在Bootstrap 3选项卡中隐藏的地图:
<script>
$(document).ready( function() {

    /* Detects when the tab is selected */
    $('a[href="#tab-id"]').on('shown.bs.tab', function() {

        /* When the tab is shown the content of the
           wrapper is regenerated and reloaded */

        $('#map-wrapper').html( $('#map-wrapper').html() );

    });
});
</script>

2
对于那些不想加载 Google Map JS 而只是使用带有 src url https://www.google.com/maps/embed/v1/place?.. 的 iframe 的人来说,这是最佳解决方案。 - gsinha

5

我曾经遇到过同样的问题,但是使用 google.maps.event.trigger(map, 'resize') 并没有解决。

我添加了一个定时器,在将 div 可见后更新地图...

// Working code

var refreshIntervalId;

function showMap() {
    document.getElementById('divMap').style.display = '';
    refreshIntervalId = setInterval(function () { updateMapTimer() }, 300);
}

function updateMapTimer() {
    clearInterval(refreshIntervalId);
    var map = new google.maps.Map(....
    ....
}

我不知道这是否是更方便的方法,但它可以正常工作!


使用setTimeout等待一次。 - Joe Austin

4
使用jQuery,您可以像这样做。这帮助我在 Umbraco CMS中加载Google Maps地图,该地图在一开始不会立即显示的选项卡上。
function waitForVisibleMapElement() {
    setTimeout(function () {
        if ($('#map_canvas').is(":visible")) {
            // Initialize your Google Map here
        } else {
            waitForVisibleMapElement();
        };
    }, 100);
};

waitForVisibleMapElement();

这是唯一对我和我的问题有效的解决方案。我在Materialize.CSS选项卡中嵌入了一个Google地图,但它没有显示地图,只显示了一个灰色背景,并且左上角只有标记和Google标志。我将选项卡内容div设置为在可见时初始化地图,现在它完美地工作了。示例 - Gorgon_Union

3
我的解决方案非常简单高效:

HTML

<div class="map-wrap">
  <div id="map-canvas"></div>
</div>

CSS(层叠样式表)
.map-wrap{
  height: 0;
  width: 0;
  overflow: hidden;
}

jQuery

$('.map-wrap').css({ height: 'auto', width: 'auto' }); // For showing your map
$('.map-wrap').css({ height: 0, width: 0 }); // For hiding your map

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接