jQuery: установить клик из цикла массива - PullRequest
9 голосов
/ 30 января 2009

У меня есть серия делений в шаблоне заголовок / тело, где щелчок по заголовку покажет рассматриваемое тело.

Все это происходит при инициализации .click на странице, готовой ...

Вместо того, чтобы делать это (что работает нормально, но это боль):

$('#show_fold_ping').click(function(){ ShowArea('#fold_ping') });
$('#show_fold_http').click(function(){ ShowArea('#fold_http') });
$('#show_fold_smtp').click(function(){ ShowArea('#fold_smtp') });
$('#show_fold_pop3').click(function(){ ShowArea('#fold_pop3') });
...

Я пытаюсь сделать это:

var Areas = ['ping','http', 'smtp', 'pop3'];

for( var i in Areas ){
    Area = '#show_fold_'+Areas[i];
    $(Area).click(function(){ alert(Area); /* ShowArea(Area); */ });
}

У меня проблема в том, что ВСЕ из них, похоже, инициализированы до последнего. IE: если pop3 - последний, щелчок по #show_fold_ [any] выдаст предупреждение '# show_fold_pop3'.

Кажется, это должно быть действительно просто. Я упускаю что-то очевидное или есть проблема с передачей строки в jQuery, о которой я не знаю?

Edit:

Эй, все это здорово. Я немного прочитал о замыканиях и функциях, вызывающих себя, и (kindasorta) понял это.

Пока у меня есть это, но щелчок, кажется, не связывает правильно. Area выдаст предупреждение с правильным значением, но без привязки. У меня все еще проблемы с областью действия, или я просто не в курсе?

$(function(){

    Areas = ['ping','http', 'smtp', 'pop3', 'imap', 'ftp', 'dns', 'tcp', 'database', 'seo'];

    for( var i = 0; i < Areas.length; i++ ){
        (function (Area) {
                            alert(Area);
            $("#show_fold_"+Area).click(function(){ alert('x'); });
        })(Areas[i]);
    }
});

Ответы [ 4 ]

12 голосов
/ 30 января 2009

Да, я слишком часто сталкиваюсь с этой проблемой. Area - глобальная переменная, так как перед ней нет var. Кроме того, не используйте for ... в конструкции.

Но вы все равно можете столкнуться с подобной проблемой. Бог знает, сколько скриптов я отлаживал из-за похожей ошибки. Выполнение следующих гарантий гарантирует правильное определение объема:

var Areas = ['ping','http', 'smtp', 'pop3'];

for( var i = 0; i < Areas.length; i++ ){
  (function(area) {
    $(area).click(function(){ alert(area); /* ShowArea(area); */ });
  })(Areas[i]);
}
3 голосов
/ 30 января 2009

Это вещь JavaScript; это не связано с jQuery. Что вы делаете, это создаете замыкание, но не понимаете должным образом, как они работают.

Возможно, вы захотите прочитать http://blog.morrisjohns.com/javascript_closures_for_dummies,, особенно примеры 5, 6 и 7.

2 голосов
/ 30 января 2009

Проверьте область действия вашей переменной "Area". Вы в основном назначаете глобальную переменную, поэтому на последней итерации «Область» выходит за пределы цикла.

1 голос
/ 30 января 2009

убедитесь, что вы добавили обработку события щелчка после загрузки DOM Вы можете включить это в элемент head:

var Areas = ['ping','http', 'smtp', 'pop3'];

$(document).ready(function() {
    $.each(Areas, function(i, v){
        var Area = '#show_fold_' + v;
        $(Area).click(function() {
            alert(Area);
        });
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...