Since you appear to be using something like jQuery, you may have the same issue I had where jQuery considers the script loading complete before Google Maps is actually completely "assembled". Using jQuery's $.getScript
(equivalent to $.ajax
with dataType: "script"
used here), it appears parts of the maps API are not yet available in the success
/done
callbacks.
$(function() {
var doSomethingMapRelatedInvolvingJQuery = function(geocoder, map) { ... };
$.ajax({
url: "https://maps.googleapis.com/maps/api/js?v=3&sensor=false",
dataType: "script"
}).done(function() {
var geocoder = new google.maps.Geocoder(), // ERROR!
activityMap = new google.maps.Map($("#map_canvas")[0], {
center: new google.maps.LatLng(0, 0),
zoom: 0,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
doSomethingMapRelatedInvolvingJQuery(geocoder, map);
});
});
For some reason, even though jQuery is saying the script has been executed already by executing the callbacks, parts of the Google Maps API are not yet available (possibly additional asynchronous stuff by Google after the first file executes).
The only solution I could find was to declare a global variable name to hold a function that Google Maps would be responsible for calling when it was completely ready. You can give it that control by adding the callback={yourfunctionname}
querystring parameter to the URL (e.g., https://maps.googleapis.com/maps/api/js?v=3&callback=googleMapsCallback&sensor=false
). It's not the prettiest solution, but it works.
var googleMapsCallback;
$(function() {
var doSomethingMapRelatedInvolvingJQuery= function(geocoder, map) { ... };
googleMapsCallback = function() {
var geocoder = new google.maps.Geocoder(), // Works when google makes the call.
activityMap = new google.maps.Map($("#map_canvas")[0], {
center: new google.maps.LatLng(0, 0),
zoom: 0,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
doSomethingMapRelatedInvolvingJQuery(geocoder, map);
};
$.ajax({
url: "https://maps.googleapis.com/maps/api/js?v=3&callback=googleMapsCallback&sensor=false",
dataType: "script"
});
});
EDIT:
I put together a proof-of-concept jsFiddle that pulls all that ugliness into a jQuery-extended method that allows for Deferred-chaining. Here's a quick example of how it can be used:
$.loadGoogleMaps().done(function () {
var geocoder = new google.maps.Geocoder();
// ... do stuff with your geocoder here ...
});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…