简体   繁体   English

帮我修复我的for循环

[英]Help me fix my for loop

Edit: Updated code after changes 编辑:更改后更新代码

I have a for loop that creates markers for a Google map. 我有一个for循环,可为Google地图创建标记。 The problem I'm having is that I am creating some info windows (the bubbles that pop up when you click a location) that I need to integrate in the loop. 我遇到的问题是我正在创建一些信息窗口(单击位置时弹出的气泡),需要将其集成到循环中。

I currently have infowindow1 through 4 and contentMarker1 through 4 outside of the loop already defined. 我目前在已定义的循环外部有infowindow1至4和contentMarker1至4。 What I need is to tell the loop to use the correct one, which should be easy since I have the i counter, but I can't get it to work, so I'm back at the start. 我需要告诉循环使用正确的循环,这应该很容易,因为我有i计数器,但是我无法使其正常工作,所以我从头开始。

If someone can point me in the right direction with regards to pointing each marker towards the correct infowindow in the addListener I'd be very happy. 如果有人可以将每个标记指向正确的方向,将每个标记指向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]));

          }

If you want to reference a global variable using another variable to derive its name, you could do 如果要使用另一个变量引用全局变量以导出其名称,则可以执行

window['infoWindow'+i]

which is exactly the same thing as 这与

window.infoWindo1

when i = 1 , and all global variables reside on the window object. i = 1 ,所有全局变量都位于window对象上。 Now, your variables may very well not be global, and honestly, regardless of whether or not they are, I don't think that code would be very neat. 现在,您的变量很可能不是全局变量,说实话, 无论它们是否是全局变量,我都不认为代码会很整洁。

It would certainly be preferable to keep your infowindows in an array, so that you may simply reference them as: 当然,最好将信息窗口保留在一个数组中,以便您可以简单地将它们引用为:

infoWindow[i]

Moving on, you'll also notice that the click listener for all the markers will trigger on a click, which occurs way after the loop has executed entirely, so the value of i will aways be 4. 继续前进,您还将注意到所有标记的点击侦听器将在点击时触发,这是循环完全执行之后发生的,因此i的值将变为4。

To work around this, you have to create a local scope for each click listener you're assigning, that encapsulates the value of the question as it is when the event is assigned: 要解决此问题,您必须为要分配的每个Click侦听器创建一个本地作用域,该作用域封装了分配事件时的问题值:

google.maps.event.addListener(marker, 'click', (function(infoWin) {
    return function() {

        // your click listener here
        // you can reference the current info window as infoWin

    }
})(infoWindow[i]));

Possible way to do it by jquery... 可能的方法来通过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]);
        });

    }

Instead of naming your info windows "infoWindow1", "infoWindow2", etc, make an array variable for your windows and then use indexes into that: 而不是为信息窗口命名为“ infoWindow1”,“ infoWindow2”等,而是为窗口创建一个数组变量,然后在其中使用索引:

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

this will avoid the need for eval or any other horrible way of choosing which window's variable has to be updated. 这样就避免了eval或更新选择哪个窗口变量的任何其他可怕方法。

the problem you observe is called closure. 您观察到的问题称为关闭。 The object google.maps.Marker got an reference to the var beach . 对象google.maps.Marker获得了对var beach的引用。 At the time the member title in google.maps.Marker is accessed the most current beach is requested wich is the last one. 在访问google.maps.Marker的会员title ,要求获取最新的beach其中最后一个是beach

The right way to solve this kind of problem is the so called immediate function: 解决这类问题的正确方法是所谓的立即函数:

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

BTW: The only thing which is able to define scope is the function . 顺便说一句:唯一可以定义范围的是function So you should define the var s at the beginning of the function in a single var statement. 所以,你应该定义var的功能在一个单一的开始小号var声明。 This pattern is called single var statement pattern . 这种模式称为单var语句模式 :D :d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM