JavaScript Closure Onclick
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"