Google 地图有效但没有显示任何地图?
Google Maps works but without any maps displaying?
我已经在我的应用程序中嵌入了一个 Google 地图。与地图互动有效。响应地图事件有效(地图 zoom_changed
、标记 dragend
等)。然而,只有地图的某些部分是可见的(例如标记和 Google 徽标),但地图本身是不可见的(至少它们不会在 95% 的时间出现)。
谁能告诉我这是怎么回事?
编辑:我将其用作 KnockoutJS 组件(插入 <gui-map></gui-map>
)。源代码如下。我不认为 KnockoutJS 的使用与地图问题有任何关系,因为:a) 所有可观察对象都正确连接并且 100% 的时间都在工作; b) 地图确实随机工作,5% 的时间没有任何代码更改。
define(['knockout', 'underscore'], function(ko, _){
function Map(params, componentInfo) {
var self = this;
var defaultPosition = {lat:-25,lng:-130};
var width = ko.isObservable(params.width) ? params.width : ko.observable(params.width ? params.width : '100px');
var height = ko.isObservable(params.height) ? params.height : ko.observable(params.height ? params.height : '100px');
var center = ko.isObservable(params.center) ? params.center : ko.observable(params.center ? params.center : defaultPosition);
var zoom = ko.isObservable(params.zoom) ? params.zoom : ko.observable(params.zoom ? params.zoom : 12);
var marker = ko.isObservable(params.marker) ? params.marker : ko.observable(params.marker ? params.marker : defaultPosition);
var element = componentInfo.element;
element.style.display = 'block';
element.style.width = width();
element.style.height = height();
width.subscribe(function(){
element.style.width = width();
});
height.subscribe(function(){
element.style.height = height();
});
function onObservableCenterChanged(newValue){
onObservableCenterChanged.changing = 1;
console.log('updating center map');
map.setCenter(newValue);
setTimeout(function(){
onObservableCenterChanged.changing = 0;
}, 500);
}
center.subscribe(onObservableCenterChanged);
function onObservableZoomChanged(newValue){
onObservableZoomChanged.changing = 1;
console.log('updating map zoom');
map.setZoom(newValue);
setTimeout(function(){
onObservableZoomChanged.changing = 0;
}, 500);
}
zoom.subscribe(onObservableZoomChanged);
var map = new google.maps.Map(element, {
center: center(),
zoom: zoom()
});
var mapMarker = new google.maps.Marker({
position:center(),
map:map,
title:'',
draggable:true
});
map.addListener('center_changed', (function(){
var mapCenterChangeTimeout;
return function(){
if (mapCenterChangeTimeout) {
clearTimeout(mapCenterChangeTimeout);
}
mapCenterChangeTimeout = setTimeout(function(){
if (!onObservableCenterChanged.changing) {
var newCenter = map.getCenter();
console.log('updating center observble');
center({
lat:newCenter.lat(),
lng:newCenter.lng()
});
}
}, 500);
};
})());
map.addListener('zoom_changed', (function(){
var mapZoomChangedTimeout;
return function(){
if (mapZoomChangedTimeout) {
clearTimeout(mapZoomChangedTimeout);
}
mapZoomChangedTimeout = setTimeout(function(){
if (!onObservableZoomChanged.changing) {
console.log('updating zoom observable');
zoom(map.getZoom());
}
}, 500);
};
})());
mapMarker.addListener('dragend', function(){
var newPosition = mapMarker.getPosition();
marker({
lat:newPosition.lat(),
lng:newPosition.lng()
});
});
}
ko.components.register('gui-map', {
template:{
require:'text!components/gui/map.html'
},
viewModel:{
createViewModel:function(params, componentInfo){
return new Map(params, componentInfo);
}
}
});
});
EDIT2:我已经通过包装 Map
函数的整个主体(var self = this;
赋值除外)成功地完成了上述工作在用 setTimeout()
调用的匿名函数中(延迟 5000 毫秒)。但是,无论如何,所有代码都在 DOMContentLoaded
事件之后执行,所以我不确定为什么这是一个问题。
问题的原因是,如果包含地图的元素不可见,Google 地图 Javascript API 无法正确呈现地图。在我的情况下,地图位于隐藏选项卡中。上面提到的超时解决了这个问题,因为延迟给了我足够长的时间在调用 Google 映射 API 的函数可以执行之前切换选项卡(如果我延迟打开选项卡直到 Google 调用了地图 API,问题会再次出现)。
我通过在地图上手动触发调整大小并手动更新地图上的各种控件解决了这个问题,例如:
google.maps.event.trigger(map, 'resize');
infoWindow.setContent(infoWindowElement);
infoWindow.close();
infoWindow.open(map, marker);
我希望这个解决方案对其他人有帮助。
我已经在我的应用程序中嵌入了一个 Google 地图。与地图互动有效。响应地图事件有效(地图 zoom_changed
、标记 dragend
等)。然而,只有地图的某些部分是可见的(例如标记和 Google 徽标),但地图本身是不可见的(至少它们不会在 95% 的时间出现)。
谁能告诉我这是怎么回事?
编辑:我将其用作 KnockoutJS 组件(插入 <gui-map></gui-map>
)。源代码如下。我不认为 KnockoutJS 的使用与地图问题有任何关系,因为:a) 所有可观察对象都正确连接并且 100% 的时间都在工作; b) 地图确实随机工作,5% 的时间没有任何代码更改。
define(['knockout', 'underscore'], function(ko, _){
function Map(params, componentInfo) {
var self = this;
var defaultPosition = {lat:-25,lng:-130};
var width = ko.isObservable(params.width) ? params.width : ko.observable(params.width ? params.width : '100px');
var height = ko.isObservable(params.height) ? params.height : ko.observable(params.height ? params.height : '100px');
var center = ko.isObservable(params.center) ? params.center : ko.observable(params.center ? params.center : defaultPosition);
var zoom = ko.isObservable(params.zoom) ? params.zoom : ko.observable(params.zoom ? params.zoom : 12);
var marker = ko.isObservable(params.marker) ? params.marker : ko.observable(params.marker ? params.marker : defaultPosition);
var element = componentInfo.element;
element.style.display = 'block';
element.style.width = width();
element.style.height = height();
width.subscribe(function(){
element.style.width = width();
});
height.subscribe(function(){
element.style.height = height();
});
function onObservableCenterChanged(newValue){
onObservableCenterChanged.changing = 1;
console.log('updating center map');
map.setCenter(newValue);
setTimeout(function(){
onObservableCenterChanged.changing = 0;
}, 500);
}
center.subscribe(onObservableCenterChanged);
function onObservableZoomChanged(newValue){
onObservableZoomChanged.changing = 1;
console.log('updating map zoom');
map.setZoom(newValue);
setTimeout(function(){
onObservableZoomChanged.changing = 0;
}, 500);
}
zoom.subscribe(onObservableZoomChanged);
var map = new google.maps.Map(element, {
center: center(),
zoom: zoom()
});
var mapMarker = new google.maps.Marker({
position:center(),
map:map,
title:'',
draggable:true
});
map.addListener('center_changed', (function(){
var mapCenterChangeTimeout;
return function(){
if (mapCenterChangeTimeout) {
clearTimeout(mapCenterChangeTimeout);
}
mapCenterChangeTimeout = setTimeout(function(){
if (!onObservableCenterChanged.changing) {
var newCenter = map.getCenter();
console.log('updating center observble');
center({
lat:newCenter.lat(),
lng:newCenter.lng()
});
}
}, 500);
};
})());
map.addListener('zoom_changed', (function(){
var mapZoomChangedTimeout;
return function(){
if (mapZoomChangedTimeout) {
clearTimeout(mapZoomChangedTimeout);
}
mapZoomChangedTimeout = setTimeout(function(){
if (!onObservableZoomChanged.changing) {
console.log('updating zoom observable');
zoom(map.getZoom());
}
}, 500);
};
})());
mapMarker.addListener('dragend', function(){
var newPosition = mapMarker.getPosition();
marker({
lat:newPosition.lat(),
lng:newPosition.lng()
});
});
}
ko.components.register('gui-map', {
template:{
require:'text!components/gui/map.html'
},
viewModel:{
createViewModel:function(params, componentInfo){
return new Map(params, componentInfo);
}
}
});
});
EDIT2:我已经通过包装 Map
函数的整个主体(var self = this;
赋值除外)成功地完成了上述工作在用 setTimeout()
调用的匿名函数中(延迟 5000 毫秒)。但是,无论如何,所有代码都在 DOMContentLoaded
事件之后执行,所以我不确定为什么这是一个问题。
问题的原因是,如果包含地图的元素不可见,Google 地图 Javascript API 无法正确呈现地图。在我的情况下,地图位于隐藏选项卡中。上面提到的超时解决了这个问题,因为延迟给了我足够长的时间在调用 Google 映射 API 的函数可以执行之前切换选项卡(如果我延迟打开选项卡直到 Google 调用了地图 API,问题会再次出现)。
我通过在地图上手动触发调整大小并手动更新地图上的各种控件解决了这个问题,例如:
google.maps.event.trigger(map, 'resize');
infoWindow.setContent(infoWindowElement);
infoWindow.close();
infoWindow.open(map, marker);
我希望这个解决方案对其他人有帮助。