谷歌地图向标记传递数据

3

我很难正确获取谷歌地图标记的信息窗口中的信息。标记已经放置在正确的位置,但是第一个和第二个信息窗口都传递了第二个地点的名称。

<script>
 function initMap() {
      var mapOptions = {
              zoom: 14,
              scrollwheel: false,
              center: new google.maps.LatLng(31.44, -100.47)
            }

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

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

      var addresses = ["3000 Main St San Angelo TX", "4001 Sunset Dr San Angelo TX"];

      var names = ['First Place', 'Second Place'];

     for(var x = 0; x < addresses.length; x++){
        var name = names[x];

        geocoder.geocode( { 'address': addresses[x]}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {


            var marker = new google.maps.Marker({
                map: map,
                position: results[0].geometry.location,
                animation: google.maps.Animation.DROP,
            });

            var contentString = name;

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

            google.maps.event.addListener(marker, 'click', function() {
              infowindow.open(map,marker);
            });
          }

        });
     }

    }

    google.maps.event.addDomListener(window, 'load', initMap);
    google.maps.event.addDomListener(window, 'resize', initMap);
</script>

我已经尝试使用setContent进行设置,但结果相同...
 google.maps.event.addListener(marker, 'click', function() {
              infowindow.setContent(names[0]);      
              infowindow.open(map,marker);
            });

2
geocoder.geocode 是异步的,当回调函数被调用时,即在你的 for 循环结束后,name 将是最后一个 names[x] - Jaromanda X
可能是在JavaScript的for循环内调用异步函数的重复问题。 - Jaromanda X
谢谢您提供的信息。我会看看能否将您提供链接中的课程应用到我的情况中。 - Miles
2个回答

3

您好,在上面的评论中已经解释了,geocoder调用在循环中不起作用。

但是,一旦您清理了它,就可以通过在标记上设置正确的数据来传递数据给标记:

 var marker = new google.maps.Marker({
            map: map,
            data: someDataProperty,// either the geocoder result or custom data
            position: results[0].geometry.location,
            animation: google.maps.Animation.DROP,
        });

然后在您的点击事件中,获取标记并使用数据属性:

google.maps.event.addListener(marker, 'click', function() 
 {
          infowindow.setContent(marker.data.name;      
          infowindow.open(map,marker);
        });

这里有一个 JS Fiddle,展示了如何使用: https://jsfiddle.net/loanburger/dh4whm25/


2
将自定义数据传递到“data”属性不会解决OP的问题。他的问题是由于“geocoder.geocode(..)”是异步函数,而他为其设置的回调闭包函数总是引用“Name”数组的最后一个元素。正如@JaromandaX的链接所指出的那样,OP的问题可以通过许多方法之一来潜在地解决,例如使用立即调用的函数、使用“.forEach()”或者他也可以同步调用异步函数(这是低效的)。 - Samuel Toh
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - TResponse

3

解决你的问题的一种方法是在 "name" 上使用函数闭包。下面的代码为循环的每个迭代创建一个匿名函数,该函数对 name 变量保持函数闭包。

geocoder.geocode({
  'address': addresses[x]
// get function closure on "name"
}, (function(name) {
  return function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      var marker = new google.maps.Marker({
        map: map,
        position: results[0].geometry.location,
        animation: google.maps.Animation.DROP,
      });
      var contentString = name;
      var infowindow = new google.maps.InfoWindow({
        content: contentString
      });
      google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map, marker);
      });
    }
  }
})(name));

概念验证代码片段

代码片段:

function initMap() {
  var mapOptions = {
    zoom: 14,
    scrollwheel: false,
    center: new google.maps.LatLng(31.44, -100.47)
  }
  var map = new google.maps.Map(document.getElementById('super_map'), mapOptions);
  var bounds = new google.maps.LatLngBounds();
  var geocoder = new google.maps.Geocoder();
  for (var x = 0; x < addresses.length; x++) {
    var name = names[x];
    geocoder.geocode({
      'address': addresses[x]
    }, (function(name) {
      // get function closure on "name"
      return function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          bounds.extend(results[0].geometry.location);
          map.fitBounds(bounds);
          var marker = new google.maps.Marker({
            map: map,
            position: results[0].geometry.location,
            animation: google.maps.Animation.DROP,
          });
          var contentString = name;
          var infowindow = new google.maps.InfoWindow({
            content: contentString
          });
          google.maps.event.addListener(marker, 'click', function() {
            infowindow.open(map, marker);
          });
        }
      }
    })(name));
  }
}

google.maps.event.addDomListener(window, 'load', initMap);
google.maps.event.addDomListener(window, 'resize', initMap);
var addresses = ["3000 Main St San Angelo TX", "4001 Sunset Dr San Angelo TX"];
var names = ['First Place', 'Second Place'];
html,
body,
#super_map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="super_map"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接