我写了一个小脚本,它从 JSON 文件加载 Google map 标记并将它们放在 map 上。该脚本应该能够处理多个实例。目前脚本看起来像这样(为了测试我使用了 this JSON file ):
<div id="map" data-file="test.json" style="width: 200px; height: 200px; "></div>
<div id="map2" data-file="test2.json" style="width: 200px; height: 200px; "></div>
<!-- JAVASCRIPT -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
var googleMaps = function() {
var $el,
apiLoaded = false;
// Init
// @public
function init(el) {
$el = $(el);
loadData($el.data('file'));
};
// Creating a marker and putting it on the map
// @private
function createMarker(data) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.lng),
map: map,
title: data.title
});
}
// JSON file and API loaded
// @private
function ready(data) {
// Basic settings
var mapOptions = {
center: new google.maps.LatLng(58, 16),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map($el[0], mapOptions);
// Create markers
$.each(data, function(key, value) {
createMarker(value);
});
}
// Load API
// @private
function loadAPI(callback) {
if (typeof google === 'object' && typeof google.maps === 'object') {
// API was already loaded
if(typeof(callback) === 'function') {
callback();
}
} else {
// API wasn't loaded yet
// Send an AJAX request
$.ajax({
url: 'http://www.google.com/jsapi/',
dataType: "script",
success: function() {
google.load('maps', '3', {
callback: function() {
// Check if callback function is set
if(typeof(callback) === 'function') {
callback();
}
},
other_params: 'sensor=false'
});
}
});
}
};
// Load JSON file
// @private
function loadData(file) {
$.ajax({
url: file,
success: function(data) {
var parsedJson = $.parseJSON(data);
loadAPI(function() {
ready(parsedJson);
});
},
error: function(request, status, error) {
// Error
console.log(error);
}
});
};
return {
init: init
}
}
});
</script>
如果我只有 .init()
一个这样的实例,它就可以工作:
googleMaps().init(document.getElementById('map'));
但是当我尝试多个实例时它就失败了:
googleMaps().init(document.getElementById('map'));
googleMaps().init(document.getElementById('map2'));
我认为它失败了,因为 .loadAPI()
和 google.load()
函数被连续调用两次,我在 .loadAPI 中检查()
如果 Google Maps API 已经加载失败(Chrome Inspector:Uncaught TypeError:Object # has no method 'Load'(Google Maps API JS 文件))。
如何确保 .loadAPI()
函数中的 AJAX 请求不会被调用两次?我可以在我的模块模式之外使用一个全局变量,我将其设置为 true,但我真的不想为此目的使用一个。还有什么我可以使用的吗?
提前致谢。
最佳答案
这里可能会出现两个不同的问题。
- 因为您每次都在调用 googleMaps() 函数,所以您正在创建该对象的一个新实例,该对象跟踪何时/是否加载了 google maps api。您需要将加载 api 的部分提取到 googleMaps 函数之外(或使用共享变量)。
- 即使您保持 loadAPI 函数不变,您仍然会遇到竞争条件,在这种情况下,加载 google map 库的 ajax 请求可能会被触发两次。您看到该错误的原因是,当您检查 loadAPI 是否可用 google 对象时,第一个 ajax 请求实际上尚未设置它。
您可以使用 Promise API 来处理此类问题。我更改了 loadAPI 方法以使用 promise ,就像我说的,它需要移到 googleMaps 函数之外
var loadAPIPromise;
// Load API
function loadAPI(callback) {
if (!loadAPIPromise) {
var deferred = $.Deferred();
$.ajax({
url: 'http://www.google.com/jsapi/',
dataType: "script",
success: function() {
google.load('maps', '3', {
callback: function() {
deferred.resolve();
},
other_params: 'sensor=false'
});
}
});
loadAPIPromise = deferred.promise();
}
loadAPIPromise.done(callback);
};
这是一个 jsfiddle 示例 http://jsfiddle.net/callado4/gA79R/4/
关于javascript - 使用 AJAX 加载 Google Maps API...但多个实例仅加载一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22019382/