This is a common mistake when dealing with JavaScript/ActionScript functions. You're having the problem because functions are closures, which means they hold references to the variables defined in scope when the functions are defined.
This means that your anonymous handler function closes around the i variable, but it stores a reference to it, not its value. Since i changes, every function holds a reference to the same variable, which will just hold the last value assigned to it.
Basically, if you want to close around a variable's specific value, you have to declare the variable (using the var statement) within the function's scope. Because of that, this might look like it should work:
for (var i:int = 0; i < 10; i++) {
var scopedI:int = i;
mc[i].addEventListener(MouseEvent.CLICK, function (e:MouseEvent) { trace(scopedI); });
}
We declare a new variable, scopedI, within the loop's scope to close around that value specifically, since that variable will be redeclared every iteration of the loop with a unique value. Unfortunately, ActionScript, like JavaScript, does not have block-level scope, only function level scope, so all variable declarations are "hoisted" to the top of the function.
This pretty much just means that your scopedI type has the same scope as i, as well as any other variable declared inside that function. So, how can we create a new scope? With more functions. Keep in mind that in ActionScript, functions are objects, so we can do crazy things like this:
(function (id) {
return function () { trace(id); };
})(7);
That bit of code creates a function, then immediately executes it with a value of 7 for the id parameter. This is useful, because now id is scoped to the inner function which we return, so that function will always print "7", no matter what happens externally.
Likewise, we can use this to scope our i variable in the loop. Your code could be updated to look like this:
function createMarkers(mapLocations){
var markerArray:Array = new Array();
for(var i = 0; i < mapLocations.length; i++){
markerArray.push(new marker());
markerArray[i].x = mapLocations[i][1];
markerArray[i].y = mapLocations[i][2];
markerArray[i].markerText.text = mapLocations[i][0].toString();
markerArray[i].addEventListener(MouseEvent.CLICK, (function (scopedI) {
return function (e:MouseEvent) { clickTarget(e, scopedI); };
})(i));
bgImage.addChild(markerArray[i]);
}
}
function clickTarget(e:MouseEvent, a){
trace(a);
}
Now, scopedI will be unique for each iteration. Yes, the syntax is a little bit messy, but this ends up being an extremely powerful and expressive feature of the language. If you can understand it, it's immensely useful.
ipreviously defined, or should this befor (var i:Number = 0 ... )? - wchargin