Keep Original Variable State Between Event Binding and Execution
Or: Binding Events Inside of a Loop with jQuery
I wrote an article on the Foliotek Development Blog about saving the state of a variable inside a closure that is not executed immediately. For example, functions passed into event binding or setTimeout(). Here is a quick rundown of the problem and the solution (using the jQuery library).
The Problem
$(function() {
$("body").append("<ul id='container'></ul>");
for (var i = ; i < 5; i++)
{
var $item = $("<li />").text("Item " + i);
$("#container").append($item);
$item.click(function() {
alert("You clicked number " + i); // always "You clicked number 5"
});
}
});
A Solution
$(function() {
$("body").append("<ul id='container'></ul>");
for (var i = ; i < 5; i++)
{
var $item = $("<li />").text("Item " + i);
$("#container").append($item);
(function() { // Closure here here instead of "bindItem()"
var ind = i;
$item.click(function() {
alert("You clicked number " + ind); // Works as expected
});
})(); // Execute immediately
}
});
The solution uses an immediately executing function to create a new scope and declare a variable "ind" that is reserved a new space in memory instead of simply referencing "i". Check out the full article for more details.
January 14th, 2011 at 6:02 am
oh, you really shouldn’t do it this way. I mean, the closure is OK, but appending HTML in each iteration? DOM is terribly slow. what you should do is store generated HTML in some array, push elements to the array in your loop, and then use Array.prototype.join() to merge the whole thing + append it to your container. also, you’d probably want to use event delegation instead of assigning event handler for each element.
January 18th, 2011 at 7:29 pm
Good tips… Usually I pay a lot of attention to performance, but in this demo I was just wanting to make what was going on with the variable state as clear as possible.
April 30th, 2012 at 9:37 pm
dancing with the stars results…
[…]these are a couple of listings to places we connect to because we think they will be well worth browsing[…]…