Flite Careers

JavaScript Event Bindings That Will Throw You for a Loop

If you build rich internet applications that rely heavily on JavaScript and frameworks such as Backbone and jQuery, chances are you have come across a quirky little thing about JavaScript event bindings, specifically when you are dealing with things within loops.

Let’s take a simple example:

You want to bind a click handler to each LI element of a UL in the DOM. Let’s say you decide on doing it by getting a reference to the items, loop over them, and bind a click handler that will alert the value of the loop counter “i”. You might expect that each item will alert “0”, “1”, “2”, etc. right? Well, if you run the example, you will see that it is not the case! Turns out that because of how JavaScript scopes things, the reference to “i” is held in each click handler function and is updated as it is incremented in the loop. So instead of getting a nice list of items that happily alert the appropriate index number, you get a list of items that all alert “5”. Annoying!

I’m not saying you would actually try to code things as I did in the example, but what are some other ways to do the same thing that would avoid this problem? Here are just a few other examples that you might consider:

1. Bypass using the loop entirely

jQuery makes it super easy to just skip the whole looping mess using the power of CSS selectors and the on() function. Without a loop or counter, we can use jQuery’s index() function to alert the index as we were trying to do in the first example too. try it

2. Use function closures

The first example works, but what if you still want to do things using a loop? Since the problem stems from the variable reference problem, using closures will safely protect the variable values and properly give you the expected result. try it

3. Use a separate function

If you don’t like using closures for whatever reason, defining a separate outside function also achieves the same result. This approach might even be a bit cleaner and/or reusable. try it

What are some ways you have solved this type of problem? I’d love to hear from our readers to see how they might have done things differently!

For further reading on this topic, I found this article rather interesting.