0

I'm dynamically inserting some html into the document (by using obj.innerHTML += 'some html'). In that html, there are images with 'imageId_X' ids (ie. imageId_1, imageId_2...). This works fine, but there's something wrong with the following code:

    for (var n = 0; n < pConfig.images.length; n++)
    {
        document.getElementById('imageId_' + n).onclick = function()
        {
            alert(n);
        }
    }

There are 4 elements in the pConfig.images and alert(n) always alerts 4. Why is this happening, what am i doing wrong?

Marius S.
  • 529
  • 2
  • 5
  • 9
  • Aside from the Closure Loop Problem: **don't** use `innerHTML+=`. This involves serialising the element's existing DOM content into an HTML string, adding to the string, and then parsing everything back into new DOM objects. This is slow and loses any non-serialisable information in the process, including any form field values, JavaScript references or event handlers. – bobince Aug 19 '10 at 08:18

3 Answers3

3

The cause of your problem is lamba expression in your code. When you define your anonymous function as onclick handler you bound it for outer variable n, which at the end of the loop is always 4 that the reason you get it always 4. To do it the way you have planned it to be you need to do the following:

for (var n = 0; n < pConfig.images.length; n++)
{
    function( n) {
      document.getElementById('imageId_' + n).onclick = function()
      {
        alert(n);
      }
    }( n);
}

Hence you define separate scope for variable.

Artem Barger
  • 40,769
  • 9
  • 59
  • 81
0

The problem is that each function you create has a reference to the same n variable - the one that is incremented. By the end of the loop, it is at 4 - and all functions you made refer to that variable with that value.

You can work around it with a closure, e.g.:

function closure(n) {
  return function() {alert(n);}
}

for (var n = 0; n < pConfig.images.length; n++)
{
    document.getElementById('imageId_' + n).onclick = closure(n);
}
sje397
  • 41,293
  • 8
  • 87
  • 103
0

Looks like you need a closure. See How do JavaScript closures work?

Community
  • 1
  • 1
Daniel Lee
  • 7,709
  • 2
  • 48
  • 57