【问题标题】:PHP javascript closure issue with google maps v3谷歌地图v3的PHP javascript关闭问题
【发布时间】:2011-09-13 05:56:03
【问题描述】:

我的应用程序在从 MySQL 数据库读取的地图上绘制了一堆标记,我想在每个信息窗口中显示一些内容。我的问题是 infowindows 只会显示我数据库中最后一个条目的内容。下面是我的代码,我只是尝试显示位置的名称。我已经尝试提醒变量以查看它们是否确实显示了正确的内容,它们是。我意识到这是一个javascript关闭问题,但我不知道如何解决这个问题。

var startLat;
var startLng;
var locationName;

<?php foreach($workstations as $workstation):?>
    startLat = "<?php echo $workstation['lat']?>";
    startLng = "<?php echo $workstation['lng']?>";
    locationName = "<?php echo $workstation['name']?>";

    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(startLat, startLng),
        map: map,
        icon: "images/purple.png"
    });

    //load all the infowindow content
    var contentString = [
                    '<div id="InfoText" style="margin: 0px; padding: 0px; overflow: hidden; border:0px">',
                    '<div class="tabs"><ul><li><a href="#tab1">General</a></li>',
                    '<li><a href="#tab2">General 2</a></li></ul>',
                    '<div id="tab1">',
                    '<b>' + locationName + '</b> - ' + locationName + '<BR>',
                    '<input id="save" type="submit" value="Reserve Today" onclick="saveStation(addMarker)" />',
                    '</div>',
                    '<div id="tab2">',
                    '</div>',
                    '</div>'
                           ].join('');

    //alert(contentString);
    var infowindow = new google.maps.InfoWindow({content: contentString});

    new google.maps.event.addListener(marker, 'click', (function(marker) {
        return function(){
            infowindow.open(map, marker);
            }
        })(marker));
<?php endforeach;?>

【问题讨论】:

    标签: php javascript jquery google-maps-api-3


    【解决方案1】:

    是的。这是一个 js 闭包问题。您有一个所有地图事件侦听器都指向的变量“标记”。试试这个:

    将其放在顶部(在 foreach 循环之前):

    function addMarkerListener( mark, mp, win )
    {
        new google.maps.event.addListener(
              mark, 
              'click', 
              function(){win.open(mp,mark)}
    }
    

    然后,在代码块末尾添加以下侦听器,而不是添加:

    addMarkerListener( marker, map, infowindow );
    

    基本上,您的版本中发生的事情是 js 说:“好的,我将创建一个函数并让标记变量填充它。明白了。”当实际调用该函数时,它会说,“我正在寻找变量‘marker’,那个变量中有什么?”不幸的是,同时这已被重新分配,现在它代表最近的分配。

    另一方面,这里的版本告诉 JavaScript,“我有这些全新的变量,它们只存在于这里,所以不要在其他任何地方寻找它们。当其中一个被点击时,然后显示相关的值给它。”单击该项目时,JS 会说,“嗯……这个变量只被分配用于这个上下文,所以我想我会使用它。”

    我可以进行变量绑定,其中涉及到一些令人兴奋的 Lambda 演算内容,但这对于这个范围来说有点多。

    【讨论】:

    • 感谢您的帮助!我试了一下,它奏效了。谢谢你的解释,真的很清楚。
    【解决方案2】:

    您不应该在 PHP 中进行循环。您不仅可以通过这种方式输出大量重复的 Javascript 块,还可以生成以下内容:

    var infowindow = …
    var infowindow = …
    var infowindow = …
    var infowindow = …
    

    您正在覆盖您自己的 infowindow 变量,所以显然只有最后一个变量存在。

    只需在 PHP 中准备数据,然后使用 Javascript 循环来处理它。这也应该使范围问题更加明显。在您的情况下,infowindow 变量有一个,可以固定如下:

    var workstations = <?php echo json_encode($workstations); ?>;
    
    for (var i = 0; i < workstation.length; i++) {
        var lat = workstations[i].lat;
        var lng = workstations[i].lng;
        var name = workstations[i].name;
    
        var marker = …
        var content = …
        var infowindow = … 
    
        (function (marker, infowindow) {
            google.maps.event.addListener(marker, 'click', function () {
                infowindow.open(map, marker);
            });
        })(marker, infowindow);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-05
      • 2014-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多