【问题标题】:Broken JS Loop with Google Maps使用谷歌地图破坏 JS 循环
【发布时间】:2010-05-13 08:41:44
【问题描述】:

我的代码在下面,我遇到了几乎相同的代码的问题,它已在 StackOverflow 上修复,但同样,它无法正常工作。我没有更改工作代码,但我确实将它包装在for...in 循环中,您将在下面看到。问题是,无论我点击什么标记,它总是会触发放置的最后一个标记/信息窗口。

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

谢谢你解决这个问题!

【问题讨论】:

    标签: javascript jquery loops


    【解决方案1】:

    当您创建每个事件处理程序闭包(函数)时,发生了什么:

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

    ...他们每个人都获得了对变量the_marker 的持久引用,不是在创建闭包时它的值。因此,该闭包函数的所有副本都使用相同的值(循环中分配给它的最后一个值)。闭包并不复杂(more here),但假设您不是第一个犯此错误的人。 :-) 这很容易做到。

    所以你想要做的是在循环迭代中捕获the_marker,这很容易做到:

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

    在那里,我们有一个函数,它使用传递给函数的参数来构建处理程序,我们在每次循环迭代时调用该函数来为我们创建处理程序。

    This answer 关于 SO 的另一个问题可能会帮助您了解闭包如何访问变量。

    【讨论】:

    • 甜蜜!有效,好吧,我遇到了另一个问题,但我想我可以从中找出答案......每个内容都显示相同的内容(请参阅 infowindow var)。所以,我试图创建一个函数来捕获它的价值。再次感谢!
    • 很好,实际上,在 buildHandler 函数中添加了 var infowindow,效果非常好,非常感谢!
    • @Oscar:Doh!我也错过了每个循环的变化。但是,嘿,称之为“留给读者的练习”部分。 ;-)
    猜你喜欢
    • 2018-12-30
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多