change:
newdiv.ondblclick = function() {alert(items[i])}
to this:
newdiv.ondblclick = (function(item) { return function() {alert(item)} })(items[i])
Look up Closures, which is what is screwing you up in this case. When you create an anonymous function using function() { }
, you are creating a closure that is bound in the scope that it was created. So inside your closure, your variable i
is the same variable that you were using in the loop. So when you double click on an item, the loop is already finished and i == 12
. It would be the same as if you put an alert(i);
directly after your for(i in items) { }
loop.
So, with that in mind, how does my second example fix that?
Well, it uses a self-executing anonymous function that accepts one variable, item
. This function returns a closure, which is bound inside its scope. The outer closure is immediately executed, passing in items[i]
, which creates a stable scope for the variable that you want to live in.
Closures can be a little mind bending if you aren't used to them, but understanding them is a big part to getting functional programming using JavaScript.
SetAttribute works because you are creating a new string that evaluates each time through the loop, rather than late-referencing the variable i
.
PS
Its probably a bad idea to use a for( in ) {}
on an array. You might get unexpected results, it should loop through all the propertys of the object not just the items in the array. its probably safer to use a regular for(var i=0;i<items.length;i++) {}