2012-08-15 6 views
0

Я видел много примеров и пытался следовать, но никто из них не работал. Поэтому я, наконец, публикую их здесь. Я не понимаю, что я делаю неправильно.Закрытие JavaScript onclick

Существует список вопросов и ответов на часто задаваемые вопросы с функцией show/hide для ответов.

Вот мой код без применения закрытия (только это цели последний вопрос, конечно)

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

Но, глядя на других примерах, которые я пытался это сделать, но не получилось:

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

Любая помощь будет оценена по достоинству. Спасибо.

+3

Вы * действительно * не должны иметь 2 элемента с одинаковым идентификатором и не должны иметь идентификаторы, начинающиеся с (или) номеров. –

+2

У вас есть вопрос № 0? – awm

+1

Также было бы проще связать с '$ ('. Faq_question')' и '$ ('. Faq_answer')' и пропустить цикл 'for'. – Ishmael

ответ

0

Существует несколько способов приблизиться к этому с помощью закрытий. Я нахожу этот метод, используя функцию самоисполнения, которую легче запомнить, как это сделать. Только строка ответа должна быть в закрытии, потому что вопрос выполняется немедленно, и затем вы можете использовать $(this) внутри обработчика события. Вот замыкание с помощью выполнения функции в себя:

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

неушивания способ, которым я иногда нахожу делает более удобная для чтения коды хранит индекс в качестве элемента .data() по этому вопросу и работает следующим образом:

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

Бум, второй работает !! Ура. Большое спасибо :-) – Monjury

+0

Упрощенная вторая версия. Я также заметил, что вы используете значения id, начинающиеся с числа. Это не было законным в более ранних версиях HTML и не рекомендуется для максимальной совместимости с браузером. – jfriend00

1

Вам необходимо добавить var в question и answer внутри крышки. В противном случае вы просто переписываете глобальные переменные каждый раз.

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'); 
     }); 
    }; 
} 
0

Проблема с первым примером заключалась в том, когда событие триггера i имеет последнее значение в цикле.

И второе, что связано с глобальными переменными, я думаю, поскольку я не видел var.

я бы решить с помощью закрытия примерно так: -

Это вызывает функцию, используя текущее значение I в петле, encapsuling его закрытия.

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')) 
} 

Я хотел бы предложить проверить http://ejohn.org/apps/learn/ который отлично учебный материал! Один из примеров имеет только эту проблему.

Смежные вопросы