Google Maps API showing grey map on ajax page load - javascript

I'm using ajax to load (into a div) the page that includes the Google map, however when it's finished loading it shows only a grey background for the map, with a Google logo in the bottom left, and a "Terms of use" link in the bottom right.
If I resize the window, then the map instantly appears. Also if I reload the entire page by pressing F5 the map loads normally. It's only when I initially load this map page using jQuery ajax that I get the grey map.
On the container page I load the maps api.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
On the map page I do everything else.
$(document).ready(function() {
initializeMap();
});
function initializeMap() {
var companyname = document.getElementById("companyname").value;
infowindow = new google.maps.InfoWindow();
latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 13,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
geo = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
bounds = new google.maps.LatLngBounds();
resultsPanel = new google.maps.DirectionsRenderer({suppressMarkers:true});
resultsPanel.setMap(map);
$("#progressbar").progressbar(0);
var companyaddress = getCompanyAddress();
setCompanyMarker(companyaddress,companyname)
}
On resize I recalculate the height so that it fills the full page. If I don't do this then the map opens with 1px height, though I don't know why. Could that be the same issue?
function calculateHeight(){
var height = $('#maincontent').height();
$('#map-canvas').css("height",height);
}
$(window).resize(function () {
calculateHeight();
});
Since the map appears when the user resizes the window manually I thought programatically calling the resize event would have the same effect, so I added this:
$(window).trigger('resize');
But that did nothing.
I tried moving the api script to the map page but that caused a "You've loaded the same script multiple times" error if I load the page more than once, which then triggered other errors. However, with this setup I was able to load the map successfully using ajax after three page loads. In other words, after loading the container page once, I have to click on the menu item (that loads the map page) three times to get it to load properly. the first two times it still fails to load properly, but after that it loads properly every time, though with a load of JavaScript errors.
I also tried loading the api script asynchronously as per this suggestion.
I also tried adding "async defer" to the api script as per this suggestion.
Neither of these suggestions worked, and now I'm here.
What is causing the map to load with a grey background when the page is loaded via ajax, and what can I do about it?

1.Make sure map-canvas have width set in CSS.
2.When exactly did you try calling google.maps.event.trigger(map,'resize'); as geocodezip suggested? You need to call it after any map-canvas div's dimension change (calculateHeight) or any change to visibility of maps div. If the map-canvas div, or it's parent, or it's parent's parent (any predecessor) has display:none set at some point, the map view won't initialise properly and you will only see gray map. Also add the map resize code into some timeout to be sure, and then lower it if it works, e.g:
function calculateHeight(){
var height = $('#maincontent').height();
$('#map-canvas').css("height",height);
setTimeout(function(){ //also do this after any other visibility/dimension change
google.maps.event.trigger(map,'resize');
}, 500);
}

Try this, which worked for me
google.maps.event.addListener(map, 'idle', function()
{
google.maps.event.trigger(map, 'resize');
});
map.setZoom( map.getZoom() - 1 );
map.setZoom( map.getZoom() + 1 );

Related

Google maps bounds/zoom not working when parent div is hidden

I have a large page of user data that is formatted for ease of use using accordion areas.
Click on the accordion control and the relevant information is shown. Click it again and it is hidden.
One of these accordions has a google map inside it with multiple pins.
When the parent accordion div is hidden bounds/zoom has no effect. When it is visible bounds/zoom works.
I can only imagine that the DOM has the collapsing parent div set to zero height and therefor Google Maps 'sees' this as zero all the way down the stack and sets bounds based on a zero height and width accordingly.
Here is a fiddle:
https://jsfiddle.net/wjebusfL/1/
The default is to have the accordion closed. When you click the open button you will see that the map contains two markers but the zoom is way off.
If you comment out the display and opacity lines in the css for .accordianarea
display: none;
opacity: 0;
You will see the accordion in an open state by default and the map bounds/zoom working OK.
Is there any way to 'force' the google map to render correctly with the accordion closed?
New answer:
After digging a little deeper, I've found that the MapOptions has a minZoom option:
minZoom (optional)
The minimum zoom level which will be displayed on the map. If omitted, or set to null, the minimum zoom from the current map type is used instead.
If we check your map_zoom() function, it's returning 8 on the first call.
If we use that 8 together with minZoom (instead of regular zoom) we'll get the desired result without calling map_zoom() a second time:
var defaultZoom = 8;
var allMarkers = new Array();
var mapOptions = {
minZoom: defaultZoom,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
Updated JSFiddle
Old answer:
Move the map_zoom() outside of map_init() so we can call it from anywhere
On $('.accordiancontrol').click, call the map_zoom() to update our zoom:
$('.accordiancontrol').click(function(){
if ($('#accordianarea' + thisId).is(":visible")) {
// Close accordianarea
}
else {
// Open accordianarea
// Update zoom
map_zoom();
}
});
Updated JSFiddle
"I can only imagine that the DOM has the collapsing parent div set to zero height and therefor Google Maps 'sees' this as zero all the way down the stack and sets bounds based on a zero height and width accordingly."
As you stated, zoom sets bounds based on a zero height and width.. What you can do is to call map_init(); on map show. That way div has height and width and map gets proper zoom bounds
$('.accordiancontrol').click(function(){
var thisId = $(this).attr('id').replace(/^\D+/g,"")
if ($('#accordianarea' + thisId).is(":visible"))
{
// Close accordianarea
}
else
{
map_init();
// Open accordianarea
}
});

Webcomponents google-map displays gray area to the right after hiding app-drawer

I have a <google-map> inside a <app-drawer-layout>, and it works fine except the map displays a gray area to the right when the drawer is hidden.
All the discussions I've found about this issue say that the solution is to trigger the resize event of the map, but it doesn't work for me. I even tried adding a delay just to be on the safe side, but still it does nothing.
document.querySelector('app-drawer').addEventListener('app-drawer-transitioned', function(){
window.setTimeout(function(){
console.log( map.clientWidth );
google.maps.event.trigger(map, 'resize');
}, 100);
});
The console output confirms that the map width has indeed changed before triggering the resize event, but the gray area persists. Even if I pan and zoom the map, the gray area is still there (although it becomes wider or narrower depending on the pan). The only thing that seems to correct it is resizing the entire browser window.
This is in Chrome on Mac btw.
Turns out that I was trying to trigger the resize event on the DOM-element instead of the Maps API object. The Maps API object can be obtained via the .map property of the <google-map> DOM-element.
This works for me
<script>
var mapElem = document.querySelector('google-map');
mapElem.addEventListener('api-load', function(e) {
var mapObj = mapElem.map;
document.querySelector('app-drawer').addEventListener('app-drawer-transitioned', function(){
google.maps.event.trigger(mapObj, 'resize');
});
});
</script>

google map show after screen resize?

I'm having problems with the google map I'm embedding, I don't understand why on load the map not appears and only appear when I resize the window, I went through different solutions in stackoverflow but they don't work for me.
Here is my js code:
<script>
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 31.554606, lng: 74.357158},
zoom: 14
});
google.maps.event.addListenerOnce(map, 'idle', function() {
google.maps.event.trigger(map, 'resize');
});
}
</script>
my div
<div id="map"></div>
when i load application it appears like
and after re size browser window it appears perfectly like this
kindly tell me how to fix this problem ?
call google.maps.event.trigger(map, 'resize') when your "div id=map" will be visible.
Please see How do I resize a Google Map with JavaScript after it has loaded?
Nothing worked for me. I was using Model box in Bootstrap to load the map. I tried everything for hours. Every time I would load the map I would see a grey box, but as soon as i would resize the browser, it would display the map. Seemed it required resizing of window. So I put all the map functionality into a function called initmap2() and displayed the fresh map inside it. and upon clicking i used
setTimeout( initMap2, 200 );
So as soon as the Modal box would open, it would display the map, and I tried working will 100 milliseconds but I guess it works with 200+ milliseconds so I kept 500ms just to be safe.
I hope this helps
I found this working only after combine two things: setTimeout and google resize.
So, at the end of initMap, I set:
google.maps.event.addListener(map, "idle", function(){
google.maps.event.trigger(map, 'resize');
});
And create a setTimeout for the initMap like this:
$(document).ready(function(){
setTimeout(initMap, 1000);
});
--
Edit
To answer #LucaC.: my initMap is a separate js, that I link into the pages. The solution above is defined in this js (the setTimeout only).
But, after a while, I noticed this problem still happening with mobile devices.
Working around: keep the setTimeout for the initMap and on the page I load the map, I've set up
$(window).load(function(){
setTimeout(function(){
google.maps.event.trigger(map, "resize");
}, 250);
});
So: i) delay anything that break the map; ii) at the end of all, resize the map after page load :)
Nothing worked for me. I was using modal box in bootstrap to load the map. i did following code may it will help you
First i load map in body with display:none like below
<div style="display:none; overflow:hidden; width:100%; height:400px;" id="map"></div>
by initMap method, map will load properly but we used display=none so that map will not display.
For display that map in model i append the div which have id="map" to id="map-modal" which is in the model. like below
$('#modal-id').on('shown.bs.modal', function () {
document.getElementById('map').style.display = "";
var mapNode = map.getDiv();
$('#map-modal').append(mapNode);
});
May it will work.
Resize your map without javascript
step 1: Go to google maps and after searching your location, click on share and
Get the Google Maps Embed
Code
step 2: code will look something like this
<iframe src="/" width="600" height="450" frameborder="0" style="border:0"
allowfullscreen></iframe>
step 3: Add a div tag around the embed code. Use the CSS class map-responsive
<div class="map-responsive">
<iframe src="/" width="600" height="450" frameborder="0" style="border:0"
allowfullscreen></iframe>
</div>
step 4: Add your Google Maps CSS
.map-responsive{
overflow:hidden;
padding-bottom:56.25%;
position:relative;
height:0;
}
.map-responsive iframe{
left:0;
top:0;
height:100%;
width:100%;
position:absolute;
}
this will make your map responsive to any screen size.!!

Recenter a Google map after container changed width

I have a google map set with the Javascript API V3. It's displayed in a div with a dynamic width, as a content pane slides up when we click on a marker.
Everything works fine, but one thing: When the pane slides up, the width of the map is changed, and so the center is displaced to the right (the pane is on the left). It is really inconvienient especially for small resolutions, where you can't even see the center after the pane is open.
I've tried the 'resize' trigger, but it doesn't seem to work... Any ideas ?
Thanks a lot !
Calling resize by it self will not acheive what you need.
What you need to do is first (before a resize occurs) get the current center of the map
var currCenter = map.getCenter();
Then you need to do something like the following, after your div is resized.
google.maps.event.trigger(map, 'resize');
map.setCenter(currCenter);
Should do the trick
UPDATE 2018-05-22
With a new renderer release in version 3.32 of Maps JavaScript API the resize event is no longer a part of Map class.
The documentation states
When the map is resized, the map center is fixed
The full-screen control now preserves center.
There is no longer any need to trigger the resize event manually.
source: https://developers.google.com/maps/documentation/javascript/new-renderer
google.maps.event.trigger(map, "resize"); doesn't have any effect starting from version 3.32
First set a variable for the current center, then use a event listener to detect a resize, and thusly set center.
//Get current center
var getCen = map.getCenter();
//Use event listener for resize on window
google.maps.event.addDomListener(window, 'resize', function() {
//Set Center
map.setCenter(getCen);
});
omarello does work but I can't upvote it. You probably forgot to refer to the var that defines your center coordinates. All "resize" does is pull the divs current width and height, it does not change anything about the map--yet!
var center = new google.maps.LatLng(39.5, -98.3);
$(document).ready(function() {
$("#fullsize").click(function(e) {
e.preventDefault();
$("#map_canvas").css({
width: '1000px'});
google.maps.event.trigger(map, "resize");
map.setCenter(center);
});
});
Hy there try this ;)
On map initialization
var currentMapCenter = null;
google.maps.event.addListener(map, 'resize', function () {
currentMapCenter = map.getCenter();
});
google.maps.event.addListener(map, 'bounds_changed', function () {
if (currentMapCenter) {
// react here
map.setCenter(currentMapCenter);
}
currentMapCenter = null;
});
After this just call when tou want the map resize.
google.maps.event.trigger(map, 'resize');

Virtual Earth maps don't show when starting as display:none

I have this code to show a map using the Virtual Earth API:
<script type="text/javascript">
function GetMap() {
var map = map = new VEMap('myMap');
map.LoadMap(new VELatLong(47.6, -122.33), 10, 'h', false);
}
$(document).ready(function () {
GetMap();
});
</script>
Show Map
<div id="myMap" style="position:relative; width:400px; height:400px; display:none;"></div>
This doesn't work and displays a black box where the map should go. If I remove the display: none; style then it works just fine. But I don't want the map to be visible when the page loads, I want the user to toggle it. Can anyone see anything wrong with my approach?
Maybe the map needs to be on display when it initializes. It happens especially if the map has to measure the dimensions of the container in order to render properly.
Either go as Diodes suggested moving the map off visual area (you could also set visibility to false) or initialize the map when you actually have to show it.
Alternately, you could move it off-screen, with left:-2000px.

Categories