最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Google map render issue after asynchronous AJAX call - Stack Overflow

programmeradmin1浏览0评论

- Introduction

Hello, i have an individual project for my course where i have to put all events of a festival on a single page. It is a javascript course, so most tasks should be handled with javascript.

The problem is, to provide a good website, that i am using a loading gif file with a message that the user has to wait until the data from AJAX got taken and handled.

This is my HTML snippet

<!-- showing loading screen -->
<div id="startup">
    <h3>Please wait until the data is done with loading</h3>
    <img src="images/ajax_load.gif" alt="loading icon" id="load_icon" />
</div>
<!-- actual content (will be displayed after loading phase) -->
<div id="siteContent">
    <div id="top">
        <label><input type="checkbox" name="cbDisabilities" id="cbDisabilities">Accessible for disabilities</label>
        <label><input type="checkbox" name="cbFree" id="cbFree">for free</label>
        <select id="selectCat">
            <option selected="selected">&nbsp;</option>
        </select>
    </div>
    <div id="mapBox"></div>
    <div id="dateBox" class="layout"></div>
    <div id="eventBox" class="layout borders"></div>
</div>
<footer>
    <p>Gentse Feesten Infos &ndash; &copy; name here TODO</p>
</footer>

With the above, i have also the next CSS for both divs,

div#siteContent {
    display: none;
}
/* style google map box */
div#mapBox {
    display: block;
    height : 500px;
    width : 500px;
    margin-top : 5px;
}

As you can see, the actual content is hidden so that the load image with the h3 text is only visible. Now, when the AJAX call is done, i have to add the markers of the event locations to the map. In meanwhile i also handle the obtained JSON data. Once this is done, i want to remove the div with the loading.gif animation and display the actual content.

Here is also an image how the data is being handled (initalize map = read GPS location + place current location marker + load map);

I have to initialize the map BEFORE the AJAX call is done because i have to add multiple markers to the map when i'm handling the data. Without the map, there will be an error when adding google map markers.

Here is a javascript snippet at the load. There are two methods, loadData() that calls AJAX and placeMap(currentLocation) to initialize the google map.

window.addEventListener('load', function() {

    // get json data - going to call AJAX
    loadData();

    // getting current location by geocoder
    var getGeoLocation = new google.maps.Geocoder();
    var currentPosition;

    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            currentPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
            placeMap(currentPosition);
        }, function() {
            handleError(100);
        });
    }
    else {
    handleError(200);
    }
    // other tasks omitted
});

This is how the map is being initialized and rendered (currentMap is a global variable to hold the reference to the google map object),

var placeMap = function(location) {
    var mapOptions = {
        zoom : 18,
        center : location,
        disableDefaultUI : true, // remove UI
        scaleControl : true,
        zoomControl : true,
        panControl : true,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    currentMap = new google.maps.Map($("mapBox"), mapOptions);
    // current position
    var mapMarker = new google.maps.Marker({
        position : location,
        map : currentMap,
        zIndex : 255
    });
    google.maps.event.addListenerOnce(currentMap, 'idle', setActive);
}

- My problem

But my problem is, that the map window doesn't render well if i use the display:none at the load. When i toggle it to inline (default browser display style), there is a gray area in the box and the map is rendering partially.

- Already tried solutions

I have already tried the solutions found on this site ;

  1. here - result : i'm getting same display result as this questioner, that gray area. But it didn't solved my problem.
  2. here - result : no rendering (box got collapsed).
  3. here - result : same as (2).

- Best solution so far BUT

So far, i have the best result with the next mand

// display content
$("startup").style.display = "none";
$("siteContent").style.display = "inline";
google.maps.event.trigger(currentMap, 'resize');

(startup = div with the loading gif image and siteContent = actual content).

This renders the map correctly after displaying visible. BUT here, the map is - sadly enough - not centered on the GPS position. The GPS marker is at the left upper corner.

If i am displaying the site without using the display="none" on the div#siteContent, then everything works as intended (The google map displays correctly with the GPS position centered on the map).

Does someone know how to solve this small rendering problem ? Preferably without use of jQuery.

- Introduction

Hello, i have an individual project for my course where i have to put all events of a festival on a single page. It is a javascript course, so most tasks should be handled with javascript.

The problem is, to provide a good website, that i am using a loading gif file with a message that the user has to wait until the data from AJAX got taken and handled.

This is my HTML snippet

<!-- showing loading screen -->
<div id="startup">
    <h3>Please wait until the data is done with loading</h3>
    <img src="images/ajax_load.gif" alt="loading icon" id="load_icon" />
</div>
<!-- actual content (will be displayed after loading phase) -->
<div id="siteContent">
    <div id="top">
        <label><input type="checkbox" name="cbDisabilities" id="cbDisabilities">Accessible for disabilities</label>
        <label><input type="checkbox" name="cbFree" id="cbFree">for free</label>
        <select id="selectCat">
            <option selected="selected">&nbsp;</option>
        </select>
    </div>
    <div id="mapBox"></div>
    <div id="dateBox" class="layout"></div>
    <div id="eventBox" class="layout borders"></div>
</div>
<footer>
    <p>Gentse Feesten Infos &ndash; &copy; name here TODO</p>
</footer>

With the above, i have also the next CSS for both divs,

div#siteContent {
    display: none;
}
/* style google map box */
div#mapBox {
    display: block;
    height : 500px;
    width : 500px;
    margin-top : 5px;
}

As you can see, the actual content is hidden so that the load image with the h3 text is only visible. Now, when the AJAX call is done, i have to add the markers of the event locations to the map. In meanwhile i also handle the obtained JSON data. Once this is done, i want to remove the div with the loading.gif animation and display the actual content.

Here is also an image how the data is being handled (initalize map = read GPS location + place current location marker + load map);

I have to initialize the map BEFORE the AJAX call is done because i have to add multiple markers to the map when i'm handling the data. Without the map, there will be an error when adding google map markers.

Here is a javascript snippet at the load. There are two methods, loadData() that calls AJAX and placeMap(currentLocation) to initialize the google map.

window.addEventListener('load', function() {

    // get json data - going to call AJAX
    loadData();

    // getting current location by geocoder
    var getGeoLocation = new google.maps.Geocoder();
    var currentPosition;

    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            currentPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
            placeMap(currentPosition);
        }, function() {
            handleError(100);
        });
    }
    else {
    handleError(200);
    }
    // other tasks omitted
});

This is how the map is being initialized and rendered (currentMap is a global variable to hold the reference to the google map object),

var placeMap = function(location) {
    var mapOptions = {
        zoom : 18,
        center : location,
        disableDefaultUI : true, // remove UI
        scaleControl : true,
        zoomControl : true,
        panControl : true,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    currentMap = new google.maps.Map($("mapBox"), mapOptions);
    // current position
    var mapMarker = new google.maps.Marker({
        position : location,
        map : currentMap,
        zIndex : 255
    });
    google.maps.event.addListenerOnce(currentMap, 'idle', setActive);
}

- My problem

But my problem is, that the map window doesn't render well if i use the display:none at the load. When i toggle it to inline (default browser display style), there is a gray area in the box and the map is rendering partially.

- Already tried solutions

I have already tried the solutions found on this site ;

  1. here - result : i'm getting same display result as this questioner, that gray area. But it didn't solved my problem.
  2. here - result : no rendering (box got collapsed).
  3. here - result : same as (2).

- Best solution so far BUT

So far, i have the best result with the next mand

// display content
$("startup").style.display = "none";
$("siteContent").style.display = "inline";
google.maps.event.trigger(currentMap, 'resize');

(startup = div with the loading gif image and siteContent = actual content).

This renders the map correctly after displaying visible. BUT here, the map is - sadly enough - not centered on the GPS position. The GPS marker is at the left upper corner.

If i am displaying the site without using the display="none" on the div#siteContent, then everything works as intended (The google map displays correctly with the GPS position centered on the map).

Does someone know how to solve this small rendering problem ? Preferably without use of jQuery.

Share Improve this question edited May 23, 2017 at 11:33 CommunityBot 11 silver badge asked Aug 6, 2013 at 12:22 KarelGKarelG 5,2444 gold badges34 silver badges53 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7
// display content
$("startup").style.display = "none";
$("siteContent").style.display = "inline";
google.maps.event.trigger(currentMap, 'resize');

(startup = div with the loading gif image and siteContent = actual content).

It seems your only problem now is?:

BUT here, the map is - sadly enough - not centered on the GPS position. The GPS marker is at the left upper corner.

so then you should:

google.maps.event.trigger(currentMap, 'resize');
currentMap.setCenter(location);

Google Maps API

Most likely, you are setting the point center before the map has resized. When it resizes it simply fills the space to the right and down, the center does not change as the map resizes.

You can create your map after you get AJAX response from the server. I don't know how you make AJAX requests, following is simple example (no jquery):

function loadData(callback) {
    var oReq = new XMLHttpRequest();
    oReq.open("GET", '/some/url', true);
    oReq.onload = callback;
    oReq.send();
}

This function accepts callback that will be executed after AJAX request pleted. Then your code:

window.addEventListener('load', function() {

    // get json data - going to call AJAX
    loadData(function(oReq) {
        var response = oReq.response;
        // parse ajax response .... (code omitted)


        // getting current location by geocoder
        var getGeoLocation = new google.maps.Geocoder();
        var currentPosition;

        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                currentPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

                // Now you can hide loading gif show your site content
                document.getElementById('startup').style.display = 'none';
                document.getElementById('siteContent').style.display = 'block';

                // Create map.
                placeMap(currentPosition);

                // .... add markers here.

            }, function() {
                handleError(100);
            });
        }
        else {
        handleError(200);
        }
        // other tasks omitted
    });
});

Even better solution would be to show loading widget right above the map using custom overlay.

i don't speak spanish but understood this answer still, and because it corrected a bug in my script, i'll try to translate it here and hope that can helps :


i hazardously discovered the solution to this problem. i have created a function called Mapa() in order to initialize google maps. in my case, i only use ajax and load the informations dynamicaly.

1) add a resize event : google.maps.event.trigger(currentMap, 'resize');

2) execute the Mapa function with jquery onload (doesn't work yet)

3) i started by executing the function after 1 second, then less, less and ... it worked perfectly at 0 milisecond so here is the solution : setTimeout(Mapa,0);

that works!

发布评论

评论列表(0)

  1. 暂无评论