2017-08-03 98 views
2

我寫了這個代碼:的onclick監聽器添加到谷歌地圖標記的JavaScript

<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的onClick。所以對於第一大廠我應該是0和第二1.但不知何故i始終是相同的值

回答

0

這是一個典型的封閉問題。 使用i變量的函數是異步回調函數。

發生的第一件事是,所有的標記都將被創建。因此i將在循環結束時爲address.locations.length。 異步回調現在引用這個確切的變量。

有一些可能的解決了這一點:

使用let聲明,如果你能使用ES6 JavaScript特性:

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)) 
} 

我希望這種方法之一能爲你工作。

0

這是因爲click事件在時間後會發生,然後i贏得最後的價值...

要解決這個問題,您可以在for循環內使用自調用匿名函數 - 這樣您將爲每個循環創建一個範圍,並且在發生時i的值將保留爲click

這就是所謂的結束 - 你可以閱讀更多有關閉herehere

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 */ 
 
    } 
 

 
}
<script async defer type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&callback=initMap"></script> 
 

 
<div id="map" style="width:500px;height:150px"></div>

+0

在地圖上顯示沒有標記.. –

+0

@SanderBakker我在Firefox中看到的,但是當試圖在IE和Chrome中看到它們時 - 他們沒有工作。現在修好了,對不起。只需刷新頁面,即可顯示所有內容,但延遲時間很短,因爲它是異步的 – codtex