Javascript Google Maps API v3为每个标记添加一个信息窗口
注意:我使用的是谷歌地图API的v3 我正在尝试为我在地图上放置的每个标记添加一个信息窗口。目前,我正在使用以下代码执行此操作:Javascript Google Maps API v3为每个标记添加一个信息窗口,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,注意:我使用的是谷歌地图API的v3 我正在尝试为我在地图上放置的每个标记添加一个信息窗口。目前,我正在使用以下代码执行此操作: 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.qs
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);
}
for(赛车道[racer_id].data.points中的变量i){
数值=赛道[racer_id]。数据。点[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});
赛道[racer_id]。标记[i]=标记;
var info=new google.maps.InfoWindow({
内容:“速度:”+values.inst+“节”
});
赛道[racer_id].info[i]=info;
google.maps.event.addListener(标记'click',函数(){
信息打开(地图、标记);
});
}
轨迹坐标推(点);
bd.extend(点);
}
问题是,当我单击一个标记时,它只显示最后添加的标记的信息窗口。另外,为了清楚起见,信息窗口显示在最后一个标记旁边,而不是单击的标记旁边。我想象我的问题在addListener部分,但我不是积极的。有什么想法吗?试试这个:
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);
}
for(赛车道[racer_id].data.points中的变量i){
数值=赛道[racer_id]。数据。点[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});
赛道[racer_id]。标记[i]=标记;
var info=new google.maps.InfoWindow({
内容:“速度:”+values.inst+“节”
});
赛道[racer_id].info[i]=info;
google.maps.event.addListener(跟踪[racer_id].markers[i],'click',函数(){
赛道[racer_id]。信息[i]。打开(地图,赛道[racer_id]。标记[i]);
});
}
轨迹坐标推(点);
bd.extend(点);
}
您在for in
循环中有:
包含在闭包中的变量共享同一个环境,因此当调用来自addListener
的单击
回调时,循环将已运行,并且info
变量将向左指向最后一个对象,该对象恰好是创建的最后一个InfoWindow
在这种情况下,解决此问题的一个简单方法是使用InfoWindow
扩展Marker
对象:
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);
});
var marker=new google.maps.marker({map:map,position:point,clickable:true});
marker.info=new google.maps.InfoWindow({
内容:“速度:”+values.inst+“节”
});
google.maps.event.addListener(标记'click',函数(){
标记信息打开(地图,标记);
});
如果您不熟悉闭包的工作方式,这可能是一个相当棘手的话题。您可以查看以下Mozilla文章以获得简要介绍:
还要记住,v3api允许在地图上显示多个
InfoWindow
s。如果您希望在此时只显示一个InfoWindow
,则应使用单个InfoWindow
对象,然后在单击标记时打开它并更改其内容()。大家好。我不知道这是否是最佳解决方案,但我想我会把它贴在这里,希望将来能帮助人们。如果您看到任何需要更改的内容,请发表评论
我的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);
}
您可以使用info\u window.close()随时关闭info\u窗口。希望这对其他人有所帮助。添加标记仍然存在关闭问题,因为它在google.maps.event.addListener范围之外使用了marker变量 更好的实施方式是:
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;
}
我还使用了来自标记的地图,这样您就不需要传递google map对象,您可能希望使用标记所属的地图。对于Earth插件API,在循环外创建气球,并将计数器传递给函数,以获取每个placemark的唯一内容
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);
});
}
在以下情况下,您可以使用此:
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.
});
我最终能够实现这一点的唯一方法是用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);
});
}
我也有类似的问题。
如果您只想在将鼠标悬停在标记上时显示一些信息,而不是单击它,那么我发现使用信息窗口的一个好方法是在标记上设置标题。这样,每当您将鼠标悬停在标记上时,标题就会显示为ALT标记。
'marker.setTitle('marker'+id);'
在我的例子中(使用Javascript inside Razor),它消除了为标记创建监听器的需要,这在Foreach循环中非常有效
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, this);
});
哈哈,我已经试过了。只是再试了一次,不幸的是它仍然不起作用。这里的问题是
i
变量,它仍然包含在闭包中。调用click
回调时,i
变量将指向循环的最后一项,因此info[i]。open
仍将打开最后一个InfoWindow
。您能解释一下我需要在哪里插入此代码段吗?我有点困惑。使用marker.info.open(map,this)在一个稍微不同的用例中为我工作。这应该是正确的答案。@DanielVassallo的答案和他提到的问题一样。效果很好,但我必须做这个.info.open(marker\u map,这个)代码>使用此.info.open(标记地图,此)
;到
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, this);
});