Google Maps API v3将InfoWindow添加到每个标记

blc*_*llo 45 javascript google-maps google-maps-api-3

注意:我正在使用Google Maps 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.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);
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我点击一个标记时,它只显示添加的最后一个标记的信息窗口.另外要清楚的是,信息窗口出现在最后一个标记旁边,而不是单击标记.我想我的问题是在addListener部分,但不是postitive.有任何想法吗?

Dan*_*llo 79

你在循环中遇到了一个非常常见的闭包问题for in:

封闭在闭包中的变量共享相同的单个环境,因此当click调用它的回调时addListener,循环将运行其路径并且info变量将指向最后一个对象,这恰好是最后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);
});
Run Code Online (Sandbox Code Playgroud)

如果您不熟悉闭包的工作方式,这可能是一个非常棘手的主题.您可以查看以下Mozilla文章以获得简要介绍:

还要记住,v3 API允许InfoWindow在地图上使用多个s.如果您打算InfoWindow当时只有一个可见,则应该使用单个InfoWindow对象,然后在单击标记时打开它并更改其内容().


ost*_*che 35

您可以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.
});
Run Code Online (Sandbox Code Playgroud)

  • 这应该是正确的答案.@DanielVassallo的答案与他所涉及的问题相同. (10认同)
  • 工作得很好,但我必须做`this.info.open(marker_map,this); ` (3认同)

cea*_*aro 9

add_marker仍然存在闭包问题,因为它使用google.maps.event.addListener范围之外的标记变量.

更好的实施方式是:

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;
}
Run Code Online (Sandbox Code Playgroud)

我也使用了标记中的地图,这样你就不需要传递谷歌地图对象,你可能想要使用标记所属的地图.