简体   繁体   中英

Broken JS Loop with Google Maps

My code is below, and I had an issue with nearly the same code, and it was fixed here on StackOverflow, but, again, its not working. I haven't changed the working code, but i did wrap it in the for...in loop youll see below. The issue is that no matter what marker I click it always triggers the last marker/infoWindow that was placed.

$(function(){
    var latlng = new google.maps.LatLng(45.522015,-122.683811);
    var settings = {
        zoom: 10,
        center: latlng,
        disableDefaultUI:true,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
    $.getJSON('api',function(json){
        for (var property in json) {
            if (json.hasOwnProperty(property)) {
                var json_data = json[property];
                var the_marker = new google.maps.Marker({
                    title:json_data.item.headline,
                    map:map,
                    clickable:true,
                    position:new google.maps.LatLng(
                        parseFloat(json_data.item.geoarray[0].latitude),
                        parseFloat(json_data.item.geoarray[0].longitude)
                    )
                });
                var infowindow = new google.maps.InfoWindow({
                    content: '<div><h1>'+json_data.item.headline+'</h1><p>'+json_data.item.full_content+'</p></div>'
                });
                new google.maps.event.addListener(the_marker, 'click', function() {
                    infowindow.open(map,the_marker);
                });
            }
        }
    });
});

Thank you for whoever figures this out!

What's going on is that when you create each of your event handler closures (functions):

new google.maps.event.addListener(the_marker, 'click', function() {
    infowindow.open(map,the_marker);
});

...they each get an enduring reference to the variable the_marker , not its value at the moment the closure is created. So all copies of that closure function use the same value (the last value assigned to it in the loop). Closures are not complicated ( more here ), but let's just say you're not the first person to make this mistake. :-) It's very easy to do.

So what you want to do is capture the value of the_marker as of that loop iteration, which is easily done:

new google.maps.event.addListener(
    the_marker,
    'click',
    buildHandler(map, the_marker));

function buildHandler(map, marker) {
    return function() {
        infowindow.open(map, marker);
    };
}

There, we have a function that builds the handler using the arguments passed into the function, and we call that function on each loop iteration to create our handler for us.

This answer to another question on SO may help you visualize how closures get access to variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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