Richard
Richard

Reputation: 65550

Using closures to capture onclick events

I'd like to correct this example:

var $foo = $('#foo');
for (var i = 0; i < 10; i++) {
    $foo.append($('<li></li>').text(i).on('click', function() {
        alert(i);
    }));
}

so that it alerts the correct value of i when clicked.

How can I do this? I know that the answer is to use a closure, but I'm not sure how to implement it.

I've tried doing

$foo.append($('<li></li>').text(i).on('click', function() {
    return (function(i) { 
        alert(i);
    })();
}));

but that returns undefined.

JSFiddle here: http://jsfiddle.net/tmcw/4phm7/1/

Upvotes: 0

Views: 185

Answers (2)

Tibos
Tibos

Reputation: 27823

You need to create a copy of the i variable for each function:

$foo.append($('<li></li>').text(i).on('click', function(copy_i) {
    return (function() { 
        alert(copy_i);
    })(i);
}));

Upvotes: 2

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382170

The standard idea is to have an immediately invoked function :

var $foo = $('#foo');
for (var i = 0; i < 10; i++) {
    (function(i){
      $foo.append($('<li></li>').text(i).on('click', function() {
        alert(i);
      }));
    })(i);
}

Upvotes: 4

Related Questions