使用Google Maps的JavaScript中的范围和关闭问题

Scope and closure problems in JavaScript using Google Maps

我有几个Google Map标记,并且我试图向每个标记添加一个click事件,但是由于某些原因,每个标记显示的文本都是相同的:(

我认为我的JS闭包有问题(闭包与JS中的作用域是同一回事吗?)

发生问题的带有标记的地图在这里:
http://www.comehike.com/outdoors/parks/trailhead.php

我在使每个标记都显示相同弹出窗口的代码中怎么做?

谢谢,
亚历克斯


是的,这是范围和闭包的问题。您正在全局范围内定义infoWindow,然后在onclick处理程序中使用它。这意味着您将始终打开在for循环的上一迭代中创建的infoWindow。

更改此代码:

1
2
3
infoWindow = new google.maps.InfoWindow({
  content: contentString
});

为此:

1
2
3
var infoWindow = new google.maps.InfoWindow({
  content: contentString
});


您需要添加此

1
2
 <script type="text/javascript"
 src="http://maps.google.com/maps/api/js?sensor=false">

否则它将一直说找不到Google。


这是一个JSFiddle演示:

我创建了一个虚拟数组,并在其中附加了名为标记的信息。然后,我们创建一个全局变量infowindow来保存您的信息窗口的一个实例。该信息窗口将在单击的标记旁边弹出。

1
2
3
4
5
var map;
var global_markers = [];    
var markers = [[37.09024, -95.712891, 'trialhead0'], [-14.235004, -51.92528, 'trialhead1'], [-38.416097, -63.616672, 'trialhead2']];

var infowindow = new google.maps.InfoWindow({});

在您的标记内填充循环。基本上,我没有为每个标记保存一个infowindow实例,而是为其附加内容,并在单击一个标记时通过onclick事件设置了带有我们保存的内容的infowindow的内容,然后在所单击的对象旁边打开了infowindow标记:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    for (var i = 0; i < markers.length; i++) {
        // obtain the attribues of each marker
        var lat = parseFloat(markers[i][0]);
        var lng = parseFloat(markers[i][1]);
        var trailhead_name = markers[i][2];

        var myLatlng = new google.maps.LatLng(lat, lng);

        var contentString ="<html><body><p>" + trailhead_name +"</p></body></html>";

        var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title:"Coordinates:" + lat +" ," + lng +" | Trailhead name:" + trailhead_name
        });

        marker['infowindow'] = contentString;

        global_markers[i] = marker;

        google.maps.event.addListener(global_markers[i], 'click', function() {
            infowindow.setContent(this['infowindow']);
            infowindow.open(map, this);
        });
    }