Google地图信息窗口在不同的标记上给出相同的结果

时间:2012-01-22 12:03:03

标签: javascript google-maps-api-3

有以下问题,infowindow,在不同的标记上给出相同的结果。 当我在 geocoder.geocode 外部调试时,它会显示正确的信息,但内部始终相同(第一个)。 suppid部分是当我在其中调试i变量时,它显示正确的值。

var optionMap = {
            zoom: 16,
            MapTypeId: google.maps.MapTypeId.ROADMAP,
            panControl: false,
            zoomControl: false,
            mapTypeControl: false,
            scaleControl: false,
            streetViewControl: false,
            overviewMapControl: false
        };

        var map = new google.maps.Map(document.getElementById('map'), optionMap);

        var geocoder = new google.maps.Geocoder();

        var latlngbounds = new google.maps.LatLngBounds();

        var icon = new google.maps.MarkerImage('images/gm_pin.png',
        new google.maps.Size(20, 34),
        new google.maps.Point(0,0),
        new google.maps.Point(10, 34));

        for(var i = 0; i < arrAddress.length; i++) {

            var address = arrAddress[i];

            var html_title = "<div class='info'><h4>" + address + "</h4></div>";

            geocoder.geocode({
                'address': address
            }, function (results, status) {

                 if(status == google.maps.GeocoderStatus.OK) {


                    var marker = new google.maps.Marker({
                        map: map,
                        icon: icon,
                        html: html_title, 
                        position: results[0].geometry.location
                    });

                    var contentString = '';

                    var infoWindow = new google.maps.InfoWindow({
                        content: contentString

                        });

                    google.maps.event.addListener(marker, 'mouseover', function() {  
                        infoWindow.setContent(this.html);
                        infoWindow.open(map, this);
                    });

                    google.maps.event.addListener(marker, 'mouseout', function() {  
                        infoWindow.close(map, this);
                    });

                    latlngbounds.extend(results[0].geometry.location);

                    if(i == arrAddress.length) {
                        map.fitBounds(latlngbounds);
                    }

                    google.maps.event.trigger(map, 'resize')
                }
            });
        }

1 个答案:

答案 0 :(得分:3)

致电Geocoder.geocode(request, callback) is asynchronous。当服务器响应时,调用回调函数。通常到这个时候,for循环已经完成了。这可以具有您描述的结果,例如每个标记具有相同的内容,因为标记是在回调中创建的,这在循环结束后发生,因此它将使用html_title中的最后一个值。

解决这个问题的方法是在循环中创建一个闭包,它将“捕获”循环内的变量html_title。这样,回调将使用正确的html_title

JavaScript中的典型显式闭包如下所示:

// Wrap a function in () and immediately call it with another ()
// Pass in the arguments in the second () 
// This causes them to be 'captured' inside the function
(function(args) { /* Do something with args */ })("Hello", 42);

在你的代码中,闭包需要在循环期间捕获一个地址:

for(var i = 0; i < arrAddress.length; i++) {
  var address = arrAddress[i];
  var html_title = "<div class='info'><h4>" + address + "</h4></div>";

  (function(address, title) {
    // Inside the closure, we can use address and html_title
    geocoder.geocode({'address': address /* captured */}, function (results, status) {
      if(status == google.maps.GeocoderStatus.OK) {
        var marker = new google.maps.Marker({
          map: map,
          icon: icon,
          html: title, /* captured */ 
          position: results[0].geometry.location
        });

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

        // ...
      }
    });
  })(address, html_title); // <- Call function, pass the vars to be captured 
}