How to load a Google Maps map inside of a hidden element

I have a page, and a Google Maps map is inside a hidden div at first. I then show the div after I click a link, but only the top left of the map shows up.

I tried having this code run after the click:

map0.onResize();

Or:

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

How can I do it?

Here is an image of what I see after showing the div with the hidden map in it:

Alt text

119123 次浏览

I just tested it myself and here's how I approached it. It is pretty straightforward.

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>

I was having the same problem and discovered that when showing the div, calling google.maps.event.trigger(map, 'resize'); appeared to resolve the issue for me.

I guess the original question is with a map that is initialized in a hidden div of the page. I solved a similar problem by resizing the map in the hidden div upon document ready, after it is initialized, regardless of its display status.

In my case, I have two maps, one is shown and one is hidden when they are initialized and I don't want to initial a map every time it is shown.

I had the same issue, and the google.maps.event.trigger(map, 'resize') wasn't working for me.

I added a timer to update the map after making the div visible...

// 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(....
....
}

I don't know if it's the more convenient way to do it, but it works!

Use:

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

If you don't have a variable map available, it should be the first element (unless you did something stupid) in the div that contains GMAP.

I had a Google map inside a Bootstrap tab, which wasn't displaying correctly. This was my fix.

// 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
});

My solution is very simple and efficient:

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

My solution was:

CSS:

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

jQuery:

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

Or if you use gmaps.js, call:

map.refresh();

when your div is shown.

I didn't like that the map would load only after the hidden div had become visible. In a carousel, for example, that doesn't really work.

This my solution is to add class to the hidden element to unhide it and hide it with position absolute instead, then render the map, and remove the class after map load.

Tested in Bootstrap Carousel.

HTML

<div class="item loading"><div id="map-canvas"></div></div>

CSS

.loading { display: block; position: absolute; }

JavaScript

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

With jQuery you could do something like this. This helped me load a Google Maps map in the Umbraco CMS on a tab that would not be visible from right away.

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


waitForVisibleMapElement();

If you have a Google Maps map inserted by copy/pasting the iframe code and you don't want to use Google Maps API, this is an easy solution.

Just execute the following JavaScript line when you show the hidden map. It just takes the iframe HTML code and insert it in the same place, so it renders again:

document.getElementById("map-wrapper").innerHTML = document.getElementById("map-wrapper").innerHTML;

jQuery version:

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

The HTML:

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

The following example works for a map initially hidden in a Bootstrap 3 tab:

<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>

Use these lines of code when you want to show a map.

$("#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);
 $("#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);

I've found this to work for me:

To hide:

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

To show:

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

How to refresh the map when you resize your div

It's not enough just to call google.maps.event.trigger(map, 'resize'); You should reset the center of the map as well.

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);
}
}

How to listen for the resize event

Angular (ng-show or ui-bootstrap collapse)

Bind directly to the element's visibility rather than to the value bound to ng-show, because the $watch can fire before the ng-show is updated (so the div will still be invisible).

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

jQuery .show()

Use the built in callback

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

Bootstrap 3 Modal

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

My googleMap div was within a container div with {display:none} until the tab clicked. I had the same problem as the OP. This worked for me:

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

Stick this code inside and at the end of your code where your container div tab is clicked and reveals your hidden div. The important thing is that your container div has to be visible before initialize can be called.

I tried a number of solutions proposed here and other pages and they didn't work for me.

If used inside Bootstrap v3 tabs, the following should work:

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

where tab-location is the ID of tab containing map.

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>

Just as John Doppelmann and HoffZ have indicated, put all code together just as follows in your div showing function or onclick event:

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

It worked perfectly for me.

Add this code before the div or pass it to a JavaScript file:

<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>

This event will be triggered after the div loads so it will refresh the map content without having to press F5.

It's also possible to just trigger the native window resize event.

Google Maps will reload itself automatically:

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

Upon showing the map I am geocoding an address and am then setting the map's center.

The google.maps.event.trigger(map, 'resize'); did not work for me.

I had to use a map.setZoom(14);.

Code is below:

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());
});
}
});