2

I have a click event attached to an element via JQuery in a loop (loop variable i):

$('#id_'+i).click(function() {ItemClick(i)});

And defined somewhere else:

function ItemClick(x) {
    alert(x);
}

As expected, this doesn't work as expected, because of the closure. I'd like to see a different number shown for each different click event, instead I just get the last value of i.

I know I need to turn the i in the closure to something that somehow isn't attached to the scope of the closure, but it eludes me, even after trying various examples. Such as:

$('#id_'+i).click(function() {ItemClick(function(x){return x)(i))});

Is there a neat and concise way of doing this?

EDIT

After looking at the duplicate, I now have two answers (please close the question):

Answer A

$('#id_'+i).data('index',i);

$('#id_'+i).click(
    function() {
        ItemClick($(this).data('index'));
    }
);

Answer B

$('#id_'+i).click(
    function(index) {
        return function () {
            ItemClick(index)
        };
    }(i)
);
Guillermo Phillips
  • 2,176
  • 1
  • 23
  • 40
  • Don't use incremental `id` attributes. It leads to headaches like this. Use a common class, and access them by index, or if needed, add an identifier in a `data` attribute. – Rory McCrossan Jul 15 '14 at 16:32

1 Answers1

0

This is a very common javascript issue that occurs because Javascript is closure/scope based, not block based.

You can fix this by creating a closure around your function call.

$('#id_' + i).on('click', function() {
    (function (index) { 
        ItemClick(index);
    }(i));
});

jsFiddle Demo

Mark Pieszak - Trilon.io
  • 61,391
  • 14
  • 82
  • 96