1

我有下面显示的代码,它在 GoogleMap 上显示 3 个标记,位置数据位于 JSON 对象中。

标记显示正确,但侦听器 (addListener) 仅在最后一个标记上工作,而不是在前 2 个标记上工作。我的代码有什么问题?

我看了很多例子,就是看不出来。:( 谢谢你的帮助!

 (function() {
window.onload = function() {

// Creating a map
var options = {  
  zoom: 3,  
  center: new google.maps.LatLng(37.09, -95.71),       
  mapTypeId: google.maps.MapTypeId.ROADMAP  
};  
var map = new google.maps.Map(document.getElementById('map'), options);  

// Creating a JSON object with weather data
var weatherData = {'weather': [
  {
    'lat': 40.756054,
    'lng': -73.986951 
  },
  {
    'lat': 47.620973, 
    'lng': -122.347276 
  },
  {
    'lat': 37.775206,
    'lng': -122.419209 
  }
]};

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

// Looping through the weather array in weatherData
for (var i = 0; i < weatherData.weather.length; i++) {

    // creating a variable that will hold the current weather object
    var weather = weatherData.weather[i];

    // Creating marker
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(weather.lat, weather.lng), 
        map: map
    });  

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


}

  }
 })();
4

1 回答 1

7

简短的回答是您需要移动创建标记并将事件侦听器添加到其自己的函数中的代码。然后在循环中,为每个标记调用该函数:

(function() {
    window.onload = function() {

        // Creating a map
        var options = {
            zoom: 3,
            center: new google.maps.LatLng( 37.09, -95.71 ),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map( document.getElementById('map'), options );

        // Creating an object with weather data
        var weatherData = {
            weather: [
                { lat: 40.756054, lng: -73.986951 },
                { lat: 47.620973, lng: -122.347276 },
                { lat: 37.775206, lng: -122.419209 }
            ]
        };

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

        // Looping through the weather array in weatherData
        for( var i = 0;  i < weatherData.weather.length;  i++ ) {
            addWeatherMarker( weatherData.weather[i] );
        }

        function addWeatherMarker( weather ) {
            // Creating marker
            var marker = new google.maps.Marker({
                position: new google.maps.LatLng( weather.lat, weather.lng ),
                map: map
            });

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

原始代码不起作用的原因是marker在循环和事件监听器中使用了变量。但是代码中只有一个marker变量,在循环开始时设置。因此,当点击处理程序被触发时 - 在所有其他代码已经完成运行很久之后 - 该marker变量具有您在循环中最后一次设置它的值。

早期标记的事件侦听器不会以某种方式获得自己的变量副本-整个程序中marker只有一个变量。marker

将代码移动到函数中可以解决此问题。现在,每次调用函数时,都会每次调用创建一个新marker变量(以及一个新weather变量)。因此,函数内部的事件侦听器可以将marker变量用于函数的特定调用。

有关更多信息,请阅读JavaScript 闭包

于 2013-04-02T21:45:56.700 回答