Javascript Google Maps API v3 为每个标记添加了一个 InfoWindow
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3158598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google Maps API v3 adding an InfoWindow to each marker
提问by Ian Burris
NOTE: I'm using v3 of the Google Maps API
注意:我使用的是 Google Maps API 的 v3
I'm trying to add an info window to each marker I put on the map. Currently I'm doing this with the following code:
我正在尝试为我放在地图上的每个标记添加一个信息窗口。目前我正在使用以下代码执行此操作:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(marker, 'click', function() {
info.open(map, marker);
});
}
track_coordinates.push(point);
bd.extend(point);
}
The problem is when I click on a marker it just displays the info window for the last marker added. Also just to be clear the info window appears next to the last marker not the marker clicked on. I'd imagine my problem is in the addListener portion but am not postitive. Any ideas?
问题是当我点击一个标记时,它只显示添加的最后一个标记的信息窗口。同样要清楚的是,信息窗口出现在最后一个标记旁边,而不是点击的标记旁边。我想我的问题是在 addListener 部分,但不是积极的。有任何想法吗?
回答by Daniel Vassallo
You are having a very common closure problemin the for inloop:
您在循环中遇到了一个非常常见的闭包问题for in:
Variables enclosed in a closure share the same single environment, so by the time the clickcallback from the addListeneris called, the loop will have run its course and the infovariable will be left pointing to the last object, which happens to be the last InfoWindowcreated.
封闭在闭包中的变量共享相同的单个环境,因此当click调用 的回调时addListener,循环将运行其过程,info变量将指向最后一个对象,该对象恰好是最后一个InfoWindow创建的对象。
In this case, one easy way to solve this problem would be to augment your Markerobject with the InfoWindow:
在这种情况下,解决此问题的一种简单方法是使用以下内容扩充您的Marker对象InfoWindow:
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
This can be quite a tricky topic, if you are not familiar with how closures work. You may to check out the following Mozilla article for a brief introduction:
如果您不熟悉闭包的工作原理,这可能是一个非常棘手的话题。您可以查看以下 Mozilla 文章进行简要介绍:
Also keep in mind, that the v3 API allows multiple InfoWindows on the map. If you intend to have just one InfoWindowvisible at the time, you should instead use a single InfoWindowobject, and then open it and change its content whenever the marker is clicked (Source).
还要记住,v3 API 允许InfoWindow地图上有多个s。如果您打算InfoWindow此时只显示一个InfoWindow对象,则应改为使用单个对象,然后在单击标记时打开它并更改其内容 ( Source)。
回答by ostapische
You can use thisin event:
您可以this在事件中使用:
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map);
// this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
回答by ceasaro
The add_marker still has a closure issue, cause it uses the marker variable outside the google.maps.event.addListener scope.
add_marker 仍然存在关闭问题,因为它使用了 google.maps.event.addListener 范围之外的标记变量。
A better implementation would be:
更好的实现是:
function add_marker(racer_id, point, note) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.note = note;
google.maps.event.addListener(marker, 'click', function() {
info_window.content = this.note;
info_window.open(this.getMap(), this);
});
return marker;
}
I also used the map from the marker, this way you don't need to pass the google map object, you probably want to use the map where the marker belongs to anyway.
我还使用了标记中的地图,这样你就不需要传递谷歌地图对象,你可能想使用标记所属的地图。
回答by Al-Chalabee
for Earth plugin APIs, create the balloon outside your loop and pass your counter to the function to get unique contents for each placemark!
对于地球插件 API,在循环外创建气球并将计数器传递给函数以获得每个地标的独特内容!
function createBalloon(placemark, i, event) {
var p = placemark;
var j = i;
google.earth.addEventListener(p, 'click', function (event) {
// prevent the default balloon from popping up
event.preventDefault();
var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(event.getTarget());
balloon.setContentString('iframePath#' + j);
ge.setBalloon(balloon);
});
}
回答by Ian Burris
Hey everyone. I don't know if this is the optimal solution but I figured I'd post it here to hopefully help people out in the future. Please comment if you see anything that should be changed.
嘿大家。我不知道这是否是最佳解决方案,但我想我会在这里发布它,希望将来能帮助人们。如果您看到任何应该更改的内容,请发表评论。
My for loops is now:
我的 for 循环现在是:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
tracks[racer_id].markers[i] = add_marker(racer_id, point, '<b>Speed:</b> ' + values.inst + ' knots<br /><b>Invalid:</b> <input type="button" value="Yes" /> <input type="button" value="No" />');
}
track_coordinates.push(point);
bd.extend(point);
}
And add_markeris defined as:
并add_marker定义为:
var info_window = new google.maps.InfoWindow({content: ''});
function add_marker(racer_id, point, note) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.note = note;
google.maps.event.addListener(marker, 'click', function() {
info_window.content = marker.note;
info_window.open(map, marker);
});
return marker;
}
You can use info_window.close() to turn off the info_window at any time. Hope this helps someone.
您可以随时使用 info_window.close() 关闭 info_window。希望这可以帮助某人。
回答by Rhibi Hamza
In My case (Using Javascript insidde Razor) This worked perfectly inside an Foreach loop
在我的情况下(使用 Javascript insidde Razor)这在 Foreach 循环中完美运行
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, this);
});
回答by JochenJung
Try this:
尝试这个:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(tracks[racer_id].markers[i], 'click', function() {
tracks[racer_id].info[i].open(map, tracks[racer_id].markers[i]);
});
}
track_coordinates.push(point);
bd.extend(point);
}
回答by John Doe
The only way I could finally get this to work was by creating an array in JavaScript. The array elements reference the various info-windows (one info-window is created for each marker on the map). Each array element contains the unique text for its appropriate map marker. I defined the JavaScript event for each info-window based on the array element. And when the event fires, I use the "this" keyword to reference the array element to reference the appropriate value to display.
我最终能让它工作的唯一方法是在 JavaScript 中创建一个数组。数组元素引用各种信息窗口(为地图上的每个标记创建一个信息窗口)。每个数组元素都包含其相应地图标记的唯一文本。我根据数组元素为每个信息窗口定义了 JavaScript 事件。当事件触发时,我使用“this”关键字来引用数组元素以引用要显示的适当值。
var map = new google.maps.Map(document.getElementById('map-div'), mapOptions);
zipcircle = [];
for (var zip in zipmap) {
var circleoptions = {
strokeOpacity: 0.8,
strokeWeight: 1,
fillOpacity: 0.35,
map: map,
center: zipmap[zip].center,
radius: 100
};
zipcircle[zipmap[zip].zipkey] = new google.maps.Circle(circleoptions);
zipcircle[zipmap[zip].zipkey].infowindowtext = zipmap[zip].popuptext;
zipcircle[zipmap[zip].zipkey].infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(zipcircle[zipmap[zip].zipkey], 'click', function() {
this.infowindow.setContent(this.infowindowtext);
this.infowindow.open(map, this);
});
}
回答by cormacio100
I had a similar problem. If all you want is for some info to be displayed when you hover over a marker, instead of clicking it, then I found that a good alternative to using an info Window was to set a title on the marker. That way whenever you hover the mouse over the marker the title displays like an ALT tag. 'marker.setTitle('Marker '+id);' It removes the need to create a listener for the marker too
我有一个类似的问题。如果您只想在将鼠标悬停在标记上时显示某些信息,而不是单击它,那么我发现使用信息窗口的一个很好的替代方法是在标记上设置标题。这样,每当您将鼠标悬停在标记上时,标题就会像 ALT 标签一样显示。'marker.setTitle('标记'+id);' 它也消除了为标记创建侦听器的需要

