Shutters !: D
This fixed code works the way you planned:
for (var i = 0; i < elem.length; i += 2) { (function () { var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function() { makeItHappen(boxa,boxb); }, false); elem[k].addEventListener("click", function() { makeItHappen(boxb,boxa); }, false); }());
Why is this fix?
for(var i=0; i < elem.length; i+=2){ var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function(){makeItHappen(boxa,boxb);}, false); elem[k].addEventListener("click", function(){makeItHappen(boxb,boxa);}, false); }
JavaScript is actually loose. It is interpreted as follows:
var i, k, boxa, boxb; for(i=0; i < elem.length; i+=2){ k = i + 1; boxa = elem[i].parentNode.id; boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function(){makeItHappen(boxa,boxb);}, false); elem[k].addEventListener("click", function(){makeItHappen(boxb,boxa);}, false); }
Due to the lifting variable , var declarations will be moved to the top of the area. Since JavaScript does not have a block area ( for , if , while , etc.), they move to the beginning of the function. Update: Compared to ES6, you can use let to get variables with block spanning.
When you run your code, the following happens: in the for loop, you add callbacks and assign boxa , but its value is overwritten at the next iteration. When the click event fires callbacks and the boxa value boxa always the last item in the list.
Using closure (closing the boxa , boxb , etc.) values, you bind this value to the scope of the click handler.
Code analysis tools like JSLint or JSHint can detect suspicious code like this. If you write a lot of code, it is worth the time to learn how to use these tools. Some IDEs have built-in features.