开发者

Help me fix my for loop

Edit: Updated code after changes

I have a for loop that creates markers for a Google map. 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. What I need is to tell the loop to use the correct one, which should be开发者_如何学Python easy since I have the i counter, but I can't get it to work, so I'm back at the start.

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.

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. 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.

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:

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...

// 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:

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.


the problem you observe is called closure. The object google.maps.Marker got an reference to the 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.

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. So you should define the vars at the beginning of the function in a single var statement. This pattern is called single var statement pattern. :D

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜