将onclick监听器添加到Google Maps Markers JavaScript

时间:2017-08-03 12:05:05

标签: javascript google-maps google-maps-api-3

我写了这段代码:

<script type="text/javascript">
    var address = JSON.parse('<?php echo $jsonLocations ?>');
    console.log(address.locations[0]);
    var latitude = '1';
    var longitude = '1';

    function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 12,
            center: new google.maps.LatLng(latitude, longitude)
        });
        for(var i = 0; i < address.locations.length; i++){

            new google.maps.Marker({
                position: new google.maps.LatLng(address.locations[i]['lat'], address.locations[i]['long']),
                map: map
            }).addListener('click', function(){
                new google.maps.InfoWindow({
                    content: '<div id="content">'+
            '<div id="siteNotice">'+
            '</div>'+
            '<h5>' + i +'</h5>'+
            '<div id="bodyContent">'+
            '</div>'+
            '</div>'
                }).open(map, this);
            })
        }
    }

</script>

我试图在标记上点击i。所以对于第一个制造商我应该是0和第二个1.但不知何故i始终是相同的值

2 个答案:

答案 0 :(得分:0)

这是因为点击事件发生的时间较晚,然后i具有最后一个值...

要解决此问题,您可以在for循环中使用自调用匿名函数 - 这样您就可以为每个循环创建一个范围,i的值将保留为{{1}当它发生时。

这称为闭包 - 您可以阅读有关闭包herehere

的更多信息

&#13;
&#13;
click
&#13;
function initMap() {

  var address = {
    locations: [{
      "lat": 30.53625,
      "lng": -111.92674,
    }, {
      "lat": 33.53625,
      "lng": -112.92674,
    }, {
      "lat": 32.53625,
      "lng": -111.92674,
    }, {
      "lat": 33.53625,
      "lng": -115.92674,
    }]
  };

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: new google.maps.LatLng(32.53625, -111.92674)
  });
  var markers = [];
  for (var i = 0; i < address.locations.length; i++) {

    (function(index) { /* <--- Self invoking function */
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(address.locations[index]['lat'], address.locations[index]['lng']),
        map: map
      });

      marker.addListener('click', function() {
        new google.maps.InfoWindow({
          content: '<div id="content">' +
            '<div id="siteNotice">' +
            '</div>' +
            '<h5>' + index + '</h5>' +
            '<div id="bodyContent">' +
            '</div>' +
            '</div>'
        }).open(map, this);

        markers.push(marker);
      });
    })(i); /* <---- Pass the index to the closure to keep its value */
  }

}
&#13;
.as-console-wrapper{
  display:none !important;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这是一个经典的闭包问题。 使用i变量的函数是异步回调。

首先发生的事情是,将创建所有标记。因此,i在循环结束时将为address.locations.length。 异步回调现在引用了这个确切的变量。

对此有一些可能的解决方法:

如果您能够使用ES6 JavaScript功能,请使用let语句:

for(let i = 0; i < address.locations.length; i++){
    [...]
}

第二个是使用这种精确绑定创建一个闭包:

for(var i = 0; i < address.locations.length; i++){
    (function(i){
        [...]
    })(i)
}

最后一个选项是使用Function.bind方法。

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

    new google.maps.Marker({
        position: new google.maps.LatLng(address.locations[i]['lat'], address.locations[i]['long']),
        map: map
    }).addListener('click', (function(i){
        new google.maps.InfoWindow({
            content: '<div id="content">'+
    '<div id="siteNotice">'+
    '</div>'+
    '<h5>' + i +'</h5>'+
    '<div id="bodyContent">'+
    '</div>'+
    '</div>'
        }).open(map, this);
    }).bind(this,i))
}

我希望其中一种方法适合你。