我的应用程序在从MySQL数据库读取的地图上绘制了一堆标记,我想在每个信息窗口中显示一些内容。我的问题是信息窗口将只显示数据库中最后一个条目的内容。下面是我的代码,我只想在其中显示位置的名称。我试着提醒变量,看看它们是否确实显示了正确的内容。我意识到这是一个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;?>
是。这是一个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微积分内容,但对于这个范围来说,这有点太多了。
您不应该在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);
}