我有这个项目使用Google和Foursquare API显示多个位置。我能够显示位置并创建标记。我的问题是如何一次显示一个信息窗口?如果我点击新位置,则其他位置信息窗口不会关闭。现在,如果我点击一个地方和另一个地方。两个信息窗口都保持打开状态。
我的代码如下。谢谢。
var initialLocations = [{
name: 'Golden Gate',
lat: 37.819929,
long: -122.478255
}, {
name: 'AT&T Park',
lat: 37.7749,
long: -122.4194
}, {
name: 'Twin Peaks',
lat: 37.7544,
long: -122.4477
},
];
var clientID = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
var clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxx";
var Location = function(data) {
var self = this;
this.name = data.name;
this.lat = data.lat;
this.long = data.long;
this.URL = "";
this.street = "";
this.city = "";
this.phone = "";
this.visible = ko.observable(true);
var foursquareURL = 'https://api.foursquare.com/v2/venues/search?ll=' + this.lat + ',' + this.long + '&client_id=' + clientID + '&client_secret=' + clientSecret + '&v=20160118' + '&query=' + this.name;
$.getJSON(foursquareURL).done(function(data) {
var results = data.response.venues[0];
self.URL = results.url || 'No url found';
self.street = results.location.formattedAddress[0];
self.city = results.location.formattedAddress[1];
self.phone = results.contact.phone || 'No phone found';;
}).fail(function() {
alert("Error found. Please refresh your page.");
});
// Info window
this.infoWindow = new google.maps.InfoWindow({
});
// Marker
this.marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.long),
map: map,
title: data.name
});
this.marker.addListener('click', function() {
self.contentString = '<div class="info-window-content"><div class="title"><b>' + data.name + "</b></div>" +
'<div class="content"><a href="' + self.URL + '">' + self.URL + "</a></div>" +
'<div class="content">' + self.street + "</div>" +
'<div class="content">' + self.city + "</div>" +
'<div class="content"><a href="tel:' + self.phone + '">' + self.phone + "</a></div></div>";
self.infoWindow.setContent(self.contentString);
self.infoWindow.open(map, this);
self.marker.setAnimation(google.maps.Animation.BOUNCE);
setTimeout(function() {
self.marker.setAnimation(null);
}, 2100);
});
this.bounce = function(place) {
google.maps.event.trigger(self.marker, 'click');
};
};
//-ViewModel
function AppViewModel() {
var self = this;
// create array of places
this.locationList = ko.observableArray([]);
this.searchLocation = ko.observable('');
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 37.77986,
lng: -122.429
}
});
initialLocations.forEach(function(locationItem) {
self.locationList.push(new Location(locationItem));
});
this.filteredList = ko.computed(function() {
var filter = self.searchLocation().toLowerCase();
if (!filter) {
self.locationList().forEach(function(locationItem) {
locationItem.visible(true);
});
return self.locationList();
} else {
return ko.utils.arrayFilter(self.locationList(), function(locationItem) {
var string = locationItem.name.toLowerCase();
var result = (string.search(filter) >= 0);
locationItem.visible(result);
return result;
});
}
}, self);
this.mapElem = document.getElementById('map');
this.mapElem.style.height = window.innerHeight - 50;
}
// Bind the VeiewModel to the view using knockout
function startApp() {
ko.applyBindings(new AppViewModel());
}
function errorHandling() {
alert("Error loading page, try refresh in page.");
}
答案 0 :(得分:0)
您必须创建一个全局变量,以保存正在显示的infoWindow:
var infowindow = null;
每当你去展示一个infowindow时,你会检查它是否为空,然后你关闭它。
if(infowindow){ infowindow.close(); }
然后创建一个新实例并将其分配给变量:
infowindow = new google.maps.InfoWindow(); ...
如果您有任何疑问,请写信给我,我会帮助您。
原谅我的英文
在这里您可以找到更多答案: Close all infowindows in Google Maps API v3
答案 1 :(得分:0)
您可以与所有infoWindow
个对象共享Location
。您需要将infoWindow
从Location
移至AppViewModel
,才能拥有此对象的实例。
然后,AppViewModel
应为:
//-ViewModel
function AppViewModel() {
var self = this;
// create array of places
this.locationList = ko.observableArray([]);
this.searchLocation = ko.observable('');
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 37.77986,
lng: -122.429
}
});
// ** Move the infoWindow from Location to AppViewModel.
var infoWindow = new google.maps.InfoWindow({
});
initialLocations.forEach(function(locationItem) {
// To each Location object, pass the same infoWindow object
self.locationList.push(new Location(locationItem, infoWindow, map));
});
// from here, the same code you have in AppViewModel
...
}
现在向Location
函数(对象)添加一个参数:
function Location(data, infoWindow, map) {
评论infoWindow
(或删除它,因为你将它作为参数):
//// Info window
//this.infoWindow = new google.maps.InfoWindow({
//});
更改click
听众:
this.marker.addListener('click', function() {
self.contentString = '<div class="info-window-content"><div class="title"><b>' + data.name + "</b></div>" +
'<div class="content"><a href="' + self.URL + '">' + self.URL + "</a></div>" +
'<div class="content">' + self.street + "</div>" +
'<div class="content">' + self.city + "</div>" +
'<div class="content"><a href="tel:' + self.phone + '">' + self.phone + "</a></div></div>";
// ** Here, remove the 'self' in order to use the infoWindow received as parameter.
infoWindow.setContent(self.contentString);
// ** Here, remove the 'self' in order to use the infoWindow received as parameter.
infoWindow.open(map, this);
self.marker.setAnimation(google.maps.Animation.BOUNCE);
setTimeout(function() {
self.marker.setAnimation(null);
}, 2100);
});
这样,您的所有Location
对象都会看到相同的infoWindow
对象。只有一个infoWindow
。
<强>更新强>
至于评论,我看到map
成为全局变量。它在AppViewModel()
中声明,但应使用var
或let
声明。我改变了它的定义。
然后,我们应该向Location
对象(地图)添加一个新参数,因为现在不是全局变量。