[英]Listener event always triggers with last element's info
I'm trying to make a map-based application, but I'm having bit of difficulty. 我正在尝试制作基于地图的应用程序,但遇到了一些困难。 The original code I had been working with added a separate InfoWindow for each marker, but I'd like to get it using a single InfoWindow for which I can set the content on the fly.
我一直在使用的原始代码为每个标记添加了一个单独的InfoWindow,但是我想使用单个InfoWindow来获取它,我可以为其动态设置内容。
However, I still seem to be a little fuzzy on how JavaScript behaves, because each time any marker is clicked the InfoWindow pops up over the last marker and the alert indicates the ID of the last entry in locations
. 但是,对于JavaScript的行为,我似乎仍然有些模糊,因为每次单击任何标记时,InfoWindow都会在最后一个标记上方弹出,并且警报会指示
locations
最后一个条目的ID。
Short snippet, problem highlighted: 简短摘要,问题突出显示:
function plotLocations(my_locations) {
locations = my_locations;
for(var i=0; i<locations.length; i++) {
var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
var icon = new google.maps.MarkerImage(
"http://goo.gl/TQpwU",
new google.maps.Size(20,32),
new google.maps.Point(0,0),
new google.maps.Point(0,32)
);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP,
icon: icon
});
// ! -- trouble right here -- ! //
google.maps.event.addListener(marker, 'click', function() {
setPopInfo(pos, i);
});
// ! -- ------------------ -- ! //
}
}
function setPopInfo(pos, index) {
pop_info.setPosition(pos);
pop_info.open(map);
window.alert(pos+"::"+index);
}
Most of the rest of my code: 我的其余大部分代码:
var map;
var mapBounds;
var locations;
var pop_info;
$(document).ready(init);
function init() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
pop_info = new google.maps.InfoWindow({
content: "I'm not populated!",
size: new google.maps.Size(100,25)
});
google.maps.event.addListener(map, 'bounds_changed', function() {
queryLocations(map.getBounds());
});
prepareGeolocation();
doGeolocation();
}
function queryLocations(bounds) {
jQuery.ajax({
url: 'http://mydomain.com/myapp/test2.php',
data: bounds.toString(),
dataType: 'json',
success: addLocations
});
}
function addLocations(new_locations) {
document.getElementById('footer').innerHTML = new_locations;
plotLocations(new_locations);
}
My reasoning for the single InfoWindow is that once a few hundred Markers and InfoWindows have been created the performance might take a nosedive. 我对单个InfoWindow的推理是,一旦创建了数百个Markers和InfoWindows,性能可能会下降。 Is what I'm trying to do feasible/advisable?
我想做的事可行/建议吗?
The problem occurs because you're defining your event listener callback function inside the loop. 发生问题是因为您正在循环内定义事件侦听器回调函数。 Closures refer to their context dynamically rather than binding to a copy of the data at the time of definition, so you have effectively created
locations.length
number of functions that are all bound to the same values of marker
, pos
and i
, which are whatever they happened to be when the loop terminated. 闭包是动态引用其上下文的,而不是在定义时绑定到数据的副本,因此您已经有效地创建了
locations.length
个函数,它们全部绑定到marker
, pos
和i
的相同值,无论它们恰好是循环终止的时间。
To work round this, you could create a function that calls addListener
outside the body of the loop, like so: 要解决此问题,您可以创建一个在循环主体外部调用
addListener
的函数,如下所示:
function plotLocations (my_locations) {
locations = my_locations;
for(var i=0; i<locations.length; i++) {
var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
var icon = new google.maps.MarkerImage(
"http://goo.gl/TQpwU",
new google.maps.Size(20,32),
new google.maps.Point(0,0),
new google.maps.Point(0,32)
);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP,
icon: icon
});
bindEvent(marker, pos, i);
}
}
function bindEvent (marker, pos, i) {
google.maps.event.addListener(marker, 'click', function() {
setPopInfo(pos, i);
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.