First of all, it looks like you are using strict mode - good ! This saved you from falling prey to the horror of implicit globals .
There are two problems in the code.
First, you are missing a declaration for i . You need to add var i; above the loop, for example:
var i; for ( i = 0; i < lists.length; i++) {
or
for (var i = 0; i < lists.length; i++) {
Note that even in this last example, the variable i is functional, not limited to the for loop.
The second is more subtle and outlined in this question and its answers : Your click handlers will have a strong link to the i variable, and not a copy from the place they were created. Therefore, when they start in response to a click, they will see i as the value of lists.length (the value that it has when the loop is completed).
In your case, this is very easy to fix (and you no longer need to declare i ): completely remove the loop and replace it with Array#forEach or jQuery.each :
lists.forEach(function(list) { $(".sa-report-btn-" + list).click(function () { $(".sa-hide-" + list).removeClass("hidden"); $(".sa-report-" + list).addClass("hidden"); }); $(".sa-hide-btn-" + list).click(function () { $(".sa-hide-" + list).addClass("hidden"); $(".sa-report-" + list).removeClass("hidden"); }); });
If you need to support really old browsers, you can either shim Array#forEach (which was added in 2009 as part of ECMAScript5), or you can use $.each ( jQuery.each ) instead:
$.each(lists, function(index, list) { // Note addition ------^ $(".sa-report-btn-" + list).click(function () { $(".sa-hide-" + list).removeClass("hidden"); $(".sa-report-" + list).addClass("hidden"); }); $(".sa-hide-btn-" + list).click(function () { $(".sa-hide-" + list).addClass("hidden"); $(".sa-report-" + list).removeClass("hidden"); }); });
Note that we do not actually use index anywhere in our callback, but we must specify it because $.each calls our callback with the index as the first argument and the value as the second. (That's why I prefer Array#forEach .) Thus, we have to accept two arguments, the one we want to be second.