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

Google maps info window give same result on different markers

本文关键字:结果 窗口 信息 谷歌地图 信息窗      更新时间:2023-09-26

有以下问题,信息窗口在不同的标记上给出相同的结果。当我在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')
                }
            });
        }

Geocoder.geocode(request, callback)的调用是异步的。当服务器响应时,会调用回调函数。通常此时,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 
}