帮我修复我的for循环

时间:2011-03-16 09:11:58

标签: javascript google-maps

修改:更改后的更新代码

我有一个for循环,可以为Google地图创建标记。我遇到的问题是我正在创建一些我需要在循环中集成的信息窗口(当你点击一个位置时弹出的气泡)。

我目前在已经定义的循环之外有infowindow1到4和contentMarker1到4。我需要的是告诉循环使用正确的循环,这应该很容易,因为我有i计数器,但我不能让它工作,所以我回到了开始。

如果有人能指出我正确的方向,将每个标记指向addListener中的正确信息窗口,我会非常高兴。

for (var i = 0; i < locations.length; i++) {
            var beach = locations[i];
            var myLatLng = new google.maps.LatLng(beach[1], beach[2]);

            var marker = new google.maps.Marker({
                position: myLatLng,
                map: map,
                icon: image,
                title: beach[0],
                zIndex: beach[3],
                animation: google.maps.Animation.DROP

            });

            google.maps.event.addListener(marker, 'click', (function(infoWindow) {
                return function() {
                    alert(myLatLng[i]);
                    map.setZoom(9); 
                    map.setCenter(myLatLng); 
                    if (currentInfoWindow != null) { 
                        currentInfoWindow.close(); 
                    }
                    infoWindow.open(map, marker);
                    currentInfoWindow = infoWindow;             
                }
            })(infoWindow[i]));

          }

4 个答案:

答案 0 :(得分:2)

如果要使用另一个变量引用全局变量来获取其名称,可以执行

window['infoWindow'+i]

完全相同
window.infoWindo1

i = 1时,所有全局变量都驻留在window对象上。现在,你的变量很可能不是全局的,老实说,无论是否,我都不认为代码会非常整洁。

将infowindows保持在一个数组中肯定是最好的,这样你就可以简单地将它们引用为:

infoWindow[i]

继续,您还会注意到所有标记的点击侦听器将在单击时触发,这在完全执行循环后的方式发生,因此{{1}的值将会离开4。

要解决此问题,您必须为要分配的每个单击侦听器创建一个本地范围,该范围封装了分配事件时问题的值:

i

答案 1 :(得分:1)

通过jquery来实现它的可能方法......

// pass in a collection of data/ array
function initializeMap(data) {

       //define map config... including start location

        // set the marker for each location (recursive jquery function)
        $.each(mapData.Details, function(i, location) {
            setupLocationMarker(map, location);
        });
    }

    // actual function used to display markers on the map
    function setupLocationMarker(map, location) {
        // create a marker
        var latlng = new google.maps.LatLng(location.LatLng.Latitude, location.LatLng.Longitude);
        var marker = new google.maps.Marker(latlng);
        map.addOverlay(marker);
        // add a marker click event
        google.maps.Event.addListener(marker, "click", function(latlng) {

            // open the info window with the location name
            map.openInfoWindow(latlng, $("<b></b>").text(location.Name + " " + location.Postcode)[0]);
        });

    }

答案 2 :(得分:1)

而不是命名您的信息窗口“infoWindow1”,“infoWindow2”等,为您的窗口创建一个数组变量,然后使用索引:

var infoWindow = [];
var contentMarker = [];
infoWindow[0] = ...
...

这将避免需要eval或任何其他可怕的方式来选择必须更新哪个窗口的变量。

答案 3 :(得分:0)

您观察到的问题称为闭包。对象google.maps.Marker获得了对var beach的引用。在访问title中的google.maps.Marker成员时,请求最后一个beach

解决此类问题的正确方法是所谓的即时功能:

    for (var i = 0; i < locations.length; i++) {
        var beach = locations[i];
        var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
        var marker = (function (currentBeach) {
            return new google.maps.Marker({
                position: myLatLng,
                map: map,
                icon: image,
                title: currentBeach[0],
                zIndex: currentBeach[3],
                animation: google.maps.Animation.DROP
            });
        }(beach))
        // MARKERE START
        google.maps.event.addListener(marker, 'click', function() { 
            map.setZoom(9); map.setCenter(myLatLng); 
            if (currentInfoWindow != null) { 
                currentInfoWindow.close(); 
            }
            infowindow.open(map, marker);
            currentInfoWindow = infowindow;
        });             
      }

顺便说一句:唯一可以定义范围的是function。因此,您应该在单个var语句中的函数开头定义var。此模式称为单个var语句模式。 :d