I want to add a Listener event to each generated marker, so that when you click a marker you are redirected to the permalink url. With the code below the permalink value is the same for every marker(it get's the last value). I've read about closure problems and that seems to be what I'm having. I don't really get the examples I've looked at though.
Can somebody take a look at my code and point me in the right direction? Any help is greatly appreciated!
downloadUrl("http://localhost/map/generatexml.php", function(data) {
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var permalink = markers[i].getAttribute("permalink");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = new google.maps.Marker({map: map,position: point,icon: icon.icon,shadow: icon.shadow,title: name});
google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
}
I want to add a Listener event to each generated marker, so that when you click a marker you are redirected to the permalink url. With the code below the permalink value is the same for every marker(it get's the last value). I've read about closure problems and that seems to be what I'm having. I don't really get the examples I've looked at though.
Can somebody take a look at my code and point me in the right direction? Any help is greatly appreciated!
downloadUrl("http://localhost/map/generatexml.php", function(data) {
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var permalink = markers[i].getAttribute("permalink");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = new google.maps.Marker({map: map,position: point,icon: icon.icon,shadow: icon.shadow,title: name});
google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
}
Share
Improve this question
edited Jul 10, 2019 at 14:45
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Feb 24, 2010 at 19:54
Daniel WestmanDaniel Westman
431 silver badge5 bronze badges
2
- 3 This is one of the most mon and repetitive questions regarding closures involving loops, possible dupes: stackoverflow./questions/1734749 stackoverflow./questions/643542 stackoverflow./questions/1582634 stackoverflow./questions/1331769 stackoverflow./questions/1552941 stackoverflow./questions/750486 stackoverflow./questions/933343 stackoverflow./questions/1579978 stackoverflow./questions/1413916 stackoverflow./questions/2314175 – Christian C. Salvadó Commented Feb 24, 2010 at 20:33
- Sorry for asking yet another closure question, but I looked through a bunch of earlier answers and just couldn't get it to work. Thanks for the links though! – Daniel Westman Commented Feb 25, 2010 at 8:36
3 Answers
Reset to default 13Try this:
for (var i = 0; i < markers.length; ++i) {
// ... like what you have already ...
(function(permalink) {
google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
})(permalink);
}
By making a new lexical scope with a copy of the "permalink" value at each iteration, your handlers should work better.
JavaScript only has function scope, so when you're declaring var's in the middle of the for-loop you're in fact only declaring them once for the entire function. First thing you should do is bring all of the var declarations to the top to make some more sense of what's going on:
downloadUrl("http://localhost/map/generatexml.php", function(data) {
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
var i, permalink, point, marker;
for (i = 0; i < markers.length; i++) {
permalink = markers[i].getAttribute("permalink");
point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
marker = new google.maps.Marker({map: map,position: point,icon: icon.icon,shadow: icon.shadow,title: name});
google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
}
Your click function will use the final value of permalink for every marker event since permalink gets replaced with a new value every time the for-loop loops.
Edit: So yeah, Pointy beat me to actually solving your problem. But there you have, at least, an explanation of the problem
We have to use closures to solve this problem
Use the below code snippet to add info window to marker
function AddInfoWidnow(marker,message)
{
var infowindow = new google.maps.InfoWindow({ content: message });
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(marker.get('map'), marker);
});
}
To see a working sample refer here