如何处理隐藏 div 内的谷歌地图(更新图片)

Posted

技术标签:

【中文标题】如何处理隐藏 div 内的谷歌地图(更新图片)【英文标题】:how to deal with google map inside of a hidden div (Updated picture) 【发布时间】:2011-05-03 03:10:10 【问题描述】:

我有一个页面,谷歌地图最初位于一个隐藏的 div 中。然后我在单击链接后显示 div,但只显示地图的左上角。

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

    map0.onResize();

或:

  google.maps.event.trigger(map0, 'resize')

任何想法。这是我在显示带有隐藏地图的 div 后看到的图像。

【问题讨论】:

已经有很多关于这个的问题,包括Google map display from a hidden area @Matt Ball - 更新后,我尝试在那里添加调整大小事件但仍然无法正常工作 @Matt Ball - 我确实让它工作了。在我创建谷歌地图对象后,我将其存储在一个全局变量中,以便稍后再次引用它,现在调用 resize 似乎有效。我试图不必每次显示地图对象时都重新创建它,因为我允许人们来回切换。 @ooo 使用下面的代码非常简单。您只需要添加一个 if 条件来检查地图对象是否已初始化。这是一个现成的代码,用于解决您的初始问题,即正确加载地图。 @philar - 是的。 .在这里谢谢。 .因此赞成:)。无论哪种方式,我都需要将变量存储在全局级别以避免重新初始化 【参考方案1】:

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

【讨论】:

为了在调整大小后保持地图的原始中心,考虑以这种方式扩展调整大小语句: var center = map.getCenter(); google.maps.event.trigger(map, 'resize'); map.setCenter(center); 不知道为什么,但我需要将解决方案包装在小的 setTimeout 中以使其工作: setTimeout(function() google.maps.event.trigger(map, 'resize'), 100); @JohnDoppelmann 感谢您的提示!不直观的原因是它为什么不保持中心,也不知道如何强制它回来。 触发'resize'事件后再次设置地图中心和缩放级别。欲了解更多信息,请参阅:code.google.com/p/gmaps-api-issues/issues/detail?id=1448 @HoffZ 这可能是由于您的调整大小代码在显示效果之前触发,超时将其延迟到显示执行,然后调整大小可以使其工作。您可能可以通过更改代码执行顺序来实现相同的效果,以确保在触发事件时,在调整地图大小之前执行 div 显示。【参考方案2】:

我自己测试了一下,这就是我的方法。很简单,如果您需要任何说明,请告诉我

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 时才实例化地图?有没有办法做到这一点,以便地图对象只实例化一次(在页面加载时)? 如果您正在调用 show() 以留出调整大小的时间,我还可以建议使用 setTimeout 延迟来调用第二个函数。【参考方案3】:
google.maps.event.trigger($("#div_ID")[0], 'resize');

如果您没有可用的变量映射,它应该是 div 中包含 GMAP 的第一个元素(除非您做了一些愚蠢的事情)。

【讨论】:

您确定可以在 div 而不是 google.map.Map 对象上触发元素吗? @SalmanA - 刚刚检查过,它对我有用(尽管地图似乎有一个新中心)。根据以前的研究,我也不知道这是可能的,所以对 CSN 表示敬意 C S N... 这对我有用,但是,它将中心位置留在错误的位置。我的地图正在初始化,就像 OP 的屏幕截图一样,它就像中心:以我的 map_canvas 的左上角为中心。关于如何让它居中绘制的想法?【参考方案4】:

我在 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
);

【讨论】:

我必须将 'shown' 替换为 'shown.bs.tab' 才能使该地图适用于隐藏在非活动选项卡中的地图。谢谢 我正在使用 SmartWizard 4,这是唯一对我有用的解决方案,而且效果很好!我将'a[href="#profileTab"]' 更改为step-2,这是包含地图DIV 的DIV 的名称。【参考方案5】:

如何在调整 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 模态调整大小方法完美地解决了我的问题,而其他大多数建议都没有。谢谢!【参考方案6】:

也可以只触发原生窗口调整大小事件。

Google 地图会自动重新加载:

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

【讨论】:

【参考方案7】:

如果您通过复制/粘贴 iframe 代码插入了 Google 地图,并且您不想使用 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>

【讨论】:

不加载 Google Map JS 而是简单地使用 iframe 和 src url https://www.google.com/maps/embed/v1/place?.. 的任何人的最佳解决方案【参考方案8】:

我遇到了同样的问题,google.maps.event.trigger(map, 'resize') 不适合我。

我所做的是在div 可见后放置一个计时器来更新地图...

//CODE WORKING

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 等待一次。【参考方案9】:

使用 jQuery,你可以做这样的事情。这帮助我在 Umbraco CMS 中的一个选项卡上加载了一个谷歌地图,该选项卡不会立即可见。

function waitForVisibleMapElement() 
    setTimeout(function () 
        if ($('#map_canvas').is(":visible")) 
            // Initialize your Google Map here
         else 
            waitForVisibleMapElement();
        ;
    , 100);
;

waitForVisibleMapElement();

【讨论】:

这是唯一对我和我的问题有效的解决方案。我在 Materialize.CSS 选项卡中有一个谷歌地图,它没有显示地图,但只显示了一个灰色背景,左角只有标记和谷歌徽标。我将选项卡内容 div 设置为在地图可见时对其进行初始化,并且效果很好。 Example【参考方案10】:

我的解决方案非常简单高效: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

【讨论】:

【参考方案11】:

或者如果您使用gmaps.js,请致电:

map.refresh();

当你的 div 显示出来时。

【讨论】:

【参考方案12】:

我猜最初的问题是在页面的隐藏 div 中初始化的地图。我通过在文档准备好后调整隐藏 div 中的地图大小解决了类似的问题,在它初始化之后,不管它的显示状态如何。就我而言,我有两张地图,一张显示,一张在初始化时隐藏,我不想在每次显示时都初始化一张地图。这是一个旧帖子,但我希望它可以帮助任何正在寻找的人。

【讨论】:

【参考方案13】:

我发现这对我有用:

隐藏:

$('.mapWrapper')
.css(
  visibility: 'hidden',
  height: 0
);

显示:

    $('.mapWrapper').css(
      visibility: 'visible',
      height: 'auto'
    );

【讨论】:

【参考方案14】:

如果在 Bootstrap v3 选项卡中使用,以下应该可以工作:

$('a[href="#tab-location"]').on('shown.bs.tab', function(e)
    var center = map.getCenter();
    google.maps.event.trigger(map, 'resize');
    map.setCenter(center);
);

其中tab-location 是包含地图的选项卡的ID。

【讨论】:

【参考方案15】:

正如 John Doppelmann 和 HoffZ 所指出的,将所有代码按如下方式放在您的 div 显示函数或 onclick 事件中:

setTimeout(function()
var center = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
);

对我来说效果很好

【讨论】:

【参考方案16】:

我的解决方案是:

CSS:

.map 
   height: 400px;
   border: #ccc solid 1px;

jQuery:

$('.map').width(555); // width of map canvas

【讨论】:

【参考方案17】:

我不喜欢地图只有在隐藏的 div 变得可见后才会加载。例如,在轮播中,这实际上是行不通的。

我的解决方案是向隐藏元素添加类以取消隐藏并使用绝对位置隐藏它,然后渲染地图,并在地图加载后删除该类。

在 Bootstrap Carousel 中测试。

HTML

&lt;div class="item loading"&gt;&lt;div id="map-canvas"&gt;&lt;/div&gt;&lt;/div&gt;

CSS

.loading  display: block; position: absolute; 

JS

$(document).ready(function()
    // render map //
    google.maps.event.addListenerOnce(map, 'idle', function()
        $('.loading').removeClass('loading');
    );

【讨论】:

【参考方案18】:

当你想显示地图时使用这行代码。

               $("#map_view").show("slow"); // use id of div which you want to show.
                    var script = document.createElement("script");
                    script.type = "text/javascript";
                    script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
                    document.body.appendChild(script);

【讨论】:

【参考方案19】:
 $("#map_view").show("slow"); // use id of div which you want to show.
     var script = document.createElement("script");
     script.type = "text/javascript";
     script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
     document.body.appendChild(script);

【讨论】:

【参考方案20】:

第一次发帖。在单击标签之前,我的 googleMap div 位于带有 display:none 的容器 div 中。和OP有同样的问题。这对我有用:

google.maps.event.addDomListener(window, 'load', setTimeout(initialize, 1));

将此代码粘贴在代码的内部和末尾,单击容器 div 选项卡并显示隐藏的 div。重要的是您的容器 div 必须在调用 initialize 之前可见。

我尝试了这里和其他页面提出的一些解决方案,但它们对我不起作用。让我知道这是否适合您。谢谢。

【讨论】:

【参考方案21】:

在 div 之前添加这段代码或将其传递给 js 文件:

<script>
    $(document).on("pageshow","#div_name",function()
       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("div_name"), myOptions);
   


</script>

这个事件会在 div 加载后触发,所以它会刷新地图内容而无需按 F5

【讨论】:

【参考方案22】:

显示地图后,我正在对地址进行地理编码,然后设置地图中心。 google.maps.event.trigger(map, 'resize'); 对我不起作用。

我必须使用map.setZoom(14);

代码如下:

document.getElementById('map').style.display = 'block';
var geocoder = new google.maps.Geocoder();
        geocoder.geocode( 'address': input.value , function(results, status) 
            if (status == google.maps.GeocoderStatus.OK) 
                map.setCenter(results[0].geometry.location);
                var marker2 = new google.maps.Marker(
                    map: map,
                    position: results[0].geometry.location
                );
                map.setZoom(14);
                marker2.addListener('dragend', function (event) 
                    $('#lat').val(event.latLng.lat());
                    $('#lng').val(event.latLng.lng());
                );

            
        );

【讨论】:

【参考方案23】:

function init_map() 
  var myOptions = 
    zoom: 16,
    center: new google.maps.LatLng(0.0, 0.0),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  ;
  map = new google.maps.Map(document.getElementById('gmap_canvas'), myOptions);
  marker = new google.maps.Marker(
    map: map,
    position: new google.maps.LatLng(0.0, 0.0)
  );
  infowindow = new google.maps.InfoWindow(
    content: 'content'
  );
  google.maps.event.addListener(marker, 'click', function() 
    infowindow.open(map, marker);
  );
  infowindow.open(map, marker);

google.maps.event.addDomListener(window, 'load', init_map);

jQuery(window).resize(function() 
  init_map();
);
jQuery('.open-map').on('click', function() 
  init_map();
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://maps.googleapis.com/maps/api/js?v=3.exp'></script>

<button type="button" class="open-map"></button>
<div style='overflow:hidden;height:250px;width:100%;'>
  <div id='gmap_canvas' style='height:250px;width:100%;'></div>
</div>

【讨论】:

以上是关于如何处理隐藏 div 内的谷歌地图(更新图片)的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Flutter 谷歌地图控制器

iPhone 应用程序内的谷歌地图集成

另一个片段内的谷歌地图 - 像 onLocationChanged 这样的功能不起作用

使用markerclusterer v3获取谷歌地图范围内的标记列表

带有标记的谷歌地图没有出现地图

来自服务器的谷歌地图实时位置更新