Skip to content Skip to sidebar Skip to footer

JavaScript Closure Onclick

I saw many examples and tried to follow but none of them would work. So I am finally posting them here. I cannot understand what I am doing wrong. There is a list of FAQ questions

Solution 1:

There are several ways to approach this using closures. I find this method using a self executing function the easiest to remember how to do. Only the answer string has to be in the closure because the question is executed immediately and you can then use $(this) inside the event handler. Here's a closure using a self executing function:

for(var i = 1; i <= faqCount; i++) {
    (function(a) {
        $('#' + i + ' .faq_question').click(function () {
            $(a).toggle();
            $(this).toggleClass('down');
        });
    })('#' + i + ' .faq_answer');
}

A non-closure way that I sometimes find makes more readable code stores the index as a .data() item on the question and works like this:

for(var i = 1; i <= faqCount; i++) {
    $('#' + i + ' .faq_question').data("answerIndex", i).click(function () {
        $('#' + $(this).data("answerIndex") + ' .faq_answer').toggle();
        $(this).toggleClass('down');
    });
}

Solution 2:

You need to add var to question and answer inside the closure. Otherwise you are just overwriting global variables each time.

var funcs = [];
function createfunc(i) {
    return function() {
        var question = '#' + i + ' .faq_question';
        var answer = '#' + i + ' .faq_answer';
        $(question).click(function () {
            $(answer).toggle();
            $(question).toggleClass('down');
        }); 
    };
}  

Solution 3:

The problem with first example was when the event triggers i has the last value in the loop.

And the second one had to do with global variables I think as I saw no var.

I would solve it using a closure like so:-

This calls a function using the current value of i in the loop, encapsuling it with a closure.

for(var i = 1; i <= faqCount; i++) {
  $(question).click((function(question, answer) {
    return function() {
      $(answer).toggle();
      $(question).toggleClass('down');
    }
  })('#' + i + ' .faq_question', '#' + i + ' .faq_answer' ))
}

I would suggest checking out http://ejohn.org/apps/learn/ which is great learning material! One of the examples has just this problem.


Post a Comment for "JavaScript Closure Onclick"