0

Working with JavaScript in IE, I used the reflected property but the problem is I have 12 items and all of alert 12.

When I use setAttribute, there's no problem.

What I have so far:

    var items = [1,2,3,4,5,6,7,8,9,10,11,12];
    for (i in items)    {
        newdiv = document.createElement("div");

        //newdiv.setAttribute("class","box");
        //newdiv.setAttribute("id",items[i]);
        //newdiv.setAttribute("ondblclick","chkItem("+items[i]+");");

        newdiv.className = "box";
        newdiv.id = items[i];
        newdiv.ondblclick = function() {alert(items[i])}
        newdiv.innerHTML = " " + items[i];
        document.getElementById("items").appendChild(newdiv);
    }
random
  • 9,774
  • 10
  • 66
  • 83
Jehong Ahn
  • 1,872
  • 1
  • 19
  • 25
  • What is the content of `items`? – Jan Jongboom Sep 07 '11 at 17:59
  • Just numbers. I edited the code. – Jehong Ahn Sep 07 '11 at 18:01
  • 1
    The problem is **there is only one variable called `i`**. This is a very common question on SO, lemme see what duplicates we can find... –  Sep 07 '11 at 18:08
  • possible duplicate of [Access outside variable in loop from Javascript closure](http://stackoverflow.com/questions/1331769/access-outside-variable-in-loop-from-javascript-closure) –  Sep 07 '11 at 18:10
  • http://stackoverflow.com/questions/6904366/for-in-with-closure-and-function-creation-issues –  Sep 07 '11 at 18:10
  • http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example –  Sep 07 '11 at 18:11
  • There really needs to be a "FAQ"-style question on this everything can be linked to -- the trick is *knowing* what to look for :p –  Sep 07 '11 at 18:15
  • Wouldn't function (){ alert(this.id); } work? see Answer below. – rlemon Sep 07 '11 at 18:19
  • Thank you very much, all of you. The real problem is that I questioned so early without study. – Jehong Ahn Sep 07 '11 at 18:33
  • This is a shame. Anyway, by your favor, now I can make the website about snack and candy. :) – Jehong Ahn Sep 07 '11 at 18:44

2 Answers2

2

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++) {}

J. Holmes
  • 18,466
  • 5
  • 47
  • 52
1

Because within the function call for double click you are referencing the element which you have already defined an ID value for... why not just use.

newdiv.ondblclick = function() {alert(this.id)}

Where this is the newdiv element.

Example Here

rlemon
  • 17,518
  • 14
  • 92
  • 123
  • Sometimes a second look it all it takes. No question is a stupid question, however some answers are.. ;) – rlemon Sep 07 '11 at 18:28
  • just realized too that the link i had provided was to the main page for jsfiddle. Forgot to save the fiddle before I copied out the url. Duh! – rlemon Sep 07 '11 at 18:30