Today I've tried to place markers with a label at the Google Maps Api. Each marker gets a eventListener. Now if a marker is clicked, the last marker reacts but not the one who's clicked. Can anybody help me?
Code example:
Code:
<script type="text/javascript">
var hole_active = 0;
function initialize() {
var winkels = [
['Store 1', 52.317281, 5.134542, 4, 'store'],
['Store 2', 52.317281, 5.136542, 5, 'store'],
['Store 3', 52.317281, 5.138542, 3, 'store'],
['Store 4', 52.317281, 5.140542, 2, 'store'],
['Store 5', 52.317281, 5.142542, 1, 'store']
];
var myOptions = {
center: new google.maps.LatLng(52.317281,5.134542),
zoom: 14,
streetViewControl: false,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var image = new google.maps.MarkerImage('', new google.maps.Size(85, 56), new google.maps.Point(0,0), new google.maps.Point(12, 56));
var markerName, i;
for (i = 0; i < winkels.length; i++) {
var markerName = winkels[i][4];
markerName = new google.maps.Marker({
position: new google.maps.LatLng(winkels[i][1], winkels[i][2]),
draggable:true,
animation: google.maps.Animation.DROP,
icon: image,
bg: 'url(assets/images/maps/marker_white.png)',
bg_active: 'url(assets/images/maps/marker_green.png)',
temp: '<img src="assets/images/maps/photo.png" style="padding:2px;" />',
map: map
});
var labelName = 'label'+i;
labelName = new Label({ map: map });
labelName.bindTo('position', markerName, 'position');
labelName.bindTo('bg', markerName, 'bg');
labelName.bindTo('text', markerName, 'temp');
google.maps.event.addListener(markerName, 'click', function() {
labelName.bindTo('bg', markerName, 'bg_active');
labelName.bindTo('text', markerName, 'temp');
hole_active = winkels[i][3];
});
}
}
function doeAktie(naam){
}
</script>
Now if a marker is clicked, the last marker reacts but not the one who's clicked.
The old closure problem eh?
An explanation:
You're creating your markers in a loop using i as a variable that is supposed to reference the current marker...however, in the scope that you are dealing with, i keeps incrementing until the end of the loop at which point it is equal to the index of the marker index that you created last. Therefore, when you event listener is run (by clicking on a marker) the function that is executed says 'now, I have an i variable in here and it wasn't declared from within me, so what was the value of i in the scope where I was created?' and it goes and gets it, which, at that point, is not the same i as when it was created.
What you need to do, is create a closure - create a new scope where the variable retains its value like this:
Code:
for (i = 0; i < winkels.length; i++) {
//...the code to create your marker....
//a closure which assigns the current value of i to a variable called num within a new scope
(function(num) {
google.maps.event.addListener(markerName, 'click', function() {
labelName.bindTo('bg', markerName, 'bg_active');
labelName.bindTo('text', markerName, 'temp');
hole_active = winkels[num][3];
});
}(i)); //placing () after this anonymous function declaration immediately invokes (i.e. executes) that function - like doing myFunc() - with the variable i as an argument
}
I highly encourage that you google 'JavaScript variable scope closure' to get more detailed (and probably clearer) information on this topic - it's a very important part of the language.
Last edited by aj_nsc; 02-29-2012 at 05:26 AM.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
With this closure i've created the solution. Instead of only placing the addListener in the new function, i've added the labelName.bindTo also in there.
The only thing i'm trying now is to adjust all labels, but the one clicked in the active state. But now I can find it myself I think.
Bookmarks