...

View Full Version : Event listeners won't use correct objects



Sarynn
09-27-2011, 08:47 PM
I feel like I must be missing something simple but I can't put my finger on it...

I'm moderately new to JS (programmed in other languages though) and am working on a Google Maps project.

This piece of code should show an alert of the region's name when a map polygon is clicked. Instead, no matter what polygon is clicked, it only does the name for the LAST iterated placemark.


for (var i = 0; i < placemarks.length; i++) {
placemark = placemarks[i]
google.maps.event.addListener(placemark.polygon, "click", function() {
alert(placemark.name);
});
}

What am I misisng? What would be a better way of handling this?

ironboy
09-27-2011, 09:11 PM
Classic problem. Has to do with JavaScript closures - or actually lack thereof.
The function assigned to the event handler will remember placemark:s last value in placemark:s scope (which is unclear to me from your code snippet - is it perhaps even global?) - which means placemarks:s value when you've finished your for loop. This is not good since all events will have the same value for placemark.

Solve it like this:
for (var i = 0; i < placemarks.length; i++) {
(function(){
var placemark = placemarks[i]
google.maps.event.addListener(placemark.polygon, "click", function() {
alert(placemark.name);
});
})();
}

xelawho
09-27-2011, 09:28 PM
or like this (which is really the same thing):


for (var i = 0; i < placemarks.length; i++) {
placemark = placemarks[i];
addlistener (placemark);
}

function addlistener (placemark){
google.maps.event.addListener(placemark.polygon, "click", function() {
alert(placemark.name);
});
}

:thumbsup:

Dormilich
09-28-2011, 07:51 AM
Has to do with JavaScript closures - or actually lack thereof.
I disagree (about the lacking part). JavaScript has Closures and the observed behaviour is according to its definition, since the value of a variable in a Closure is determined on execution time (when the event occurs), not on definition time (inside the loop).

ironboy
09-28-2011, 11:15 AM
Sorry, for being unclear:
Javascript has/is built on closures. The code presented was lacking them.

Kor
09-28-2011, 11:57 AM
There is also, a no less elegant solution, to use the closure, but to create custom properties for the objects within the loop:



for (var i = 0; i < placemarks.length; i++) {
placemark = placemarks[i];
placemark.polygon.pname=placemark.name;
google.maps.event.addListener(placemark.polygon, "click", function() {
alert(this.pname);
});
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum