[英]multiple markers with unique infowindows using google maps javascript api v3
I know this question is posted all over stack overflow. 我知道这个问题是遍布堆栈溢出的。 But I've been working at it for days, and none of the solutions have worked. 但是我已经在这里工作了好几天,但没有一个解决方案有效。 I'll post everything I'm doing and maybe someone will see my mistake. 我会发布我正在做的一切,也许有人会看到我的错误。 I'd much rather leave comments on the other existing questions but there is a requirement of 50 rep... I hope there are enough comments to help you read the code but let me summarize. 我更愿意对其他现有问题发表评论,但需要50个代表...我希望有足够的评论来帮助您阅读代码,但让我总结一下。 I have the initialize function for the map. 我有地图的初始化功能。 Since my maps is about directions there is a calcRoute() function. 由于我的地图是关于方向的,因此有一个calcRoute()函数。 This function gets a route from google, and puts in on the map. 此功能从谷歌获取路线,并放入地图。 I also place some markers along the route, that's the parksToPlaceArray. 我还在路线上放置了一些标记,那就是parksToPlaceArray。 so if the ajax returns successfully I parse through the data and add the markers. 所以如果ajax成功返回,我会解析数据并添加标记。 and just below creating the marker I have attempted to add an event listener for the infowindow, but it does not work. 在下面创建标记我试图为infowindow添加一个事件监听器,但它不起作用。 I'd like to get a concept going because I would like to have a title, small description, maybe a thumbnail, and have the title link to the details page. 我想得到一个概念,因为我想有一个标题,小描述,可能是一个缩略图,并有标题链接到详细信息页面。
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var infowindow;
var parksToPlaceArray = [];
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var desoto = new google.maps.LatLng(27.521692, -82.643475); // just a default start value to the map
var mapOptions = {
zoom: 15,
center: desoto
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
directionsDisplay.setMap(map);
// Resize stuff...
// makes the map responsive by continuously centering the map on resize
google.maps.event.addDomListener(window, "resize", function () {
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);
});
infowindow = new google.map.InfoWindow();
// marker click
//google.maps.event.addListener(marker, 'click', function () {
// //map.setZoom(8);
// //map.setCenter(marker.getPosition());
//});
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
// This ajax call goes out to loadparksbyroute.cshtml with the bounds of the route, and returns a json array of possible parks
$.ajax({
dataType: "json",
type: "POST",
url: "/getDataPage",
success: function (ajaxResponse) {
// SUCCESS FUNCTION - RETURNED FROM AJAX ==================================================================
var parksResponse = ajaxResponse;
// we now have a list of all locations in the zone
parksToPlaceArray = getParks();
for (i = 0; i < parksToPlaceArray.length; i++) {
var myLatlng = new google.maps.LatLng(parksToPlaceArray[i].addresses[0].latitude, parksToPlaceArray[i].addresses[0].longitude);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName
});
//google.maps.event.addListener(marker, 'click', (function (marker, i) {
// return function () {
// infowindow.setContent('<h3>' + this.title + '</h3>');
// infowindow.open(map, marker);
// }
//})(marker, i));
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent('<h3>' + this.title + '</h3>');
infowindow.open(map, this);
});
}
},
// END OF SUCCESS FUNCTION FROM AJAX CALL
error: function (response) {
console.log('error');
}
});
}
});
}
// when the page loads initialize the map
google.maps.event.addDomListener(window, 'load', initialize);
I've tried a few different places to put the event listener. 我已经尝试了几个不同的地方来放置事件监听器。 I can't really put it in the initialize since the actual markers are brought in using ajax. 我不能真正把它放在初始化中,因为实际的标记是使用ajax引入的。 I have a list of locations 'parksToPlaceArray' and I loop through it creating a marker and placing it. 我有一个位置'parksToPlaceArray'的列表,我循环通过它创建一个标记并放置它。 Everything works except for the ability to click on a marker. 一切都有效,除了点击标记的能力。
EDIT: So I made a change based on the comments, and now clicking any marker shows one infowindow over a single item. 编辑:所以我根据评论进行了更改,现在点击任何标记显示一个项目的一个信息。 Any marker click will show the same single info window over the same marker 任何标记点击都会在同一标记上显示相同的单个信息窗口
for (i = 0; i < parksToPlaceArray.length; i++) {
var myLatlng = new google.maps.LatLng(parksToPlaceArray[i].addresses[0].latitude, parksToPlaceArray[i].addresses[0].longitude);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName
});
//google.maps.event.addListener(marker, 'click', (function (marker, i) {
// return function () {
// infowindow.setContent('<h3>' + this.title + '</h3>');
// infowindow.open(map, marker);
// }
//})(marker, i));
var contentString = parksToPlaceArray[i].recAreaName;
marker.infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, 'click', function () {
marker.infowindow.open(map, marker);
});
}
To clarify: you want to know how to close the other info windows when you click on a marker. 澄清一下:您想知道在单击标记时如何关闭其他信息窗口。
The answer is to use a single info window. 答案是使用单个信息窗口。 So you were closer with your original code. 所以你更接近原始代码。
To make the original code work you should write your for loop like this (because there is a function closure inside the loop) 要使原始代码工作,你应该像这样编写for循环(因为循环中有一个函数闭包)
for (i = 0; i < parksToPlaceArray.length; i++) (function(i) {
// ...
})(i);
So you should write 所以你应该写
for (i = 0; i < parksToPlaceArray.length; i++) (function(i) {
var myLatlng = new google.maps.LatLng(
parksToPlaceArray[i].addresses[0].latitude,
parksToPlaceArray[i].addresses[0].longitude);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName
});
marker.addListener('click', function() {
infowindow.setContent('<h3>' + marker.title + '</h3>');
infowindow.open(map, marker);
});
})(i);
I believe your issue is in the way you are handling the infowindows. 我相信你的问题与你处理信息的方式有关。 You should be following a pattern along the lines of: 你应该按照以下方式遵循一种模式:
What you are doing is: 你在做什么是:
Try Modifying: 尝试修改:
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent('<h3>' + this.title + '</h3>');
infowindow.open(map, this);
});
To something along the lines of: 对于以下内容:
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName
});
marker.infowindow = new google.maps.InfoWindow({ content: '<h3>' + this.title + '</h3>' });
google.maps.event.addListener(marker, 'click', function () {
this.infowindow.open(map, this);
});
Ok I got it with help from the comment 好的,我在评论的帮助下得到了它
The problem was setting up an infowindow for the marker as a property, and the event listener used this instead of marker. 问题是为标记设置了一个infowindow作为属性,事件监听器使用它而不是标记。 Here are the changes I made, and I removed the global infowindow entirely 以下是我所做的更改,我完全删除了全局信息窗口
var contentString = '<h3>' + parksToPlaceArray[i].recAreaName + '</h3>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: parksToPlaceArray[i].recAreaName,
infowindow: infowindow
});
google.maps.event.addListener(marker, 'click', function () {
this.infowindow.open(map, this);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.