2011-01-02 1 views
3

Я пытаюсь заполнить список ul некоторыми элементами li и дать каждому элементу li ссылку, которая вызывает ту же функцию с другим аргументом. Однако, похоже, что это не работает, я добавил код ниже, CheckForNewMail вызывается при загрузке документа. Кто-нибудь может помочь мне?JQuery Привязать событие click к добавленному элементу с аргументом

function CheckForNewMail() { 
    ////////////////////////////////////////////////////////////////// 
    // This will be dynamic 
    MailInInbox[0] = new Array("0", "Mail One"); 
    MailInInbox[1] = new Array("12", "Mail Two"); 
    MailInInbox[2] = new Array("32", "Mail Three"); 
    MailInInbox[3] = new Array("5", "Mail Four"); 
    ////////////////////////////////////////////////////////////////////// 
    $('#mail-in-inbox').children().remove(); 

    size = 4; element = $('#mail-in-inbox'); 
    for(i = 0; i < size; ++i) { 
     var link = $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>'); 
     link.live('click', function() { 
      LoadMailById(i); 
     }); 
     li = $('<li></li>'); 
     li.append(link); 
     element.append(li);  
    } 
} 

function LoadMailById(id) { 
    alert("Button "+ id +" clicked!"); 
} 

ответ

0
LoadMailById(i); 

i является ссылкой здесь и увеличение на каждой итерации для-. Таким образом, после цикла for он сохраняет значение размера; 4.

1

Есть пара вопросов.

Во-первых, это не то, как вы используете .live(). Метод .live() вызывается против объекта jQuery, которому был задан селектор. Вы можете сделать это в любой момент (даже до загрузки DOM), и любые клики на странице, которые соответствуют селектору, будут запускать обработчик.

В вашем случае, это бы что-то вроде:

$('.inbox-link').live('click',function() { 
    // whatever 
}); 

В вашем случае, где вы назначить отдельный обработчик для каждого элемента, вы должны использовать .bind вместо live().

Как уже упоминалось, у вас не будет правильного значения i в обработчике. Вы можете использовать $.each(), чтобы преодолеть это.

$.each(MailInInbox, function(i) { 
    var link = $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>'); 
    link.bind('click', function() { 
     LoadMailById(i); 
    }); 
    $('<li></li>').append(link).appendTo(element);  
}); 

Теперь вы будете иметь правильное значение i в обработчик для каждого link.

2

Одна из проблем заключается в том, что переменная i будет всегда соответствовать последней ссылке, поскольку к тому времени, когда пользователь нажмет на какую-либо ссылку, цикл завершится. Один из способов, чтобы исправить это было бы использовать .data() method связать часть информации с каждым li элемента:

link.data('mailId', i); // within the loop 

Затем вы можете связать один обработчик событий для всех входящих сообщений ссылки внутри #mail-in-inbox:

$('#mail-in-inbox').on('click', '.inbox-link', function() { 
    LoadMailById($(this).data('mailId')); 
}); 

Отредактировано для добавления: .on() было введено в jQuery 1.7. Если вы используете jQuery 1.6 или старше, используйте .delegate() или .live() (как в вопросе, так и в оригинальной версии этого ответа).

0
link.live('click', (function(index) { 
     return function() { 
      LoadMailById(index); 
     }; 
    )(i); 
    }); 

Я думаю, что это должно работать, чтобы исправить проблему. Анонимная функция принимает ваш аргумент i и связывает его с индексом переменной, так что, когда происходит щелчок, он не использует значение i, оставшееся от конца цикла, но вместо этого использует его значение во время привязки.

2

Во-первых, я делаю предположение здесь:

  • Что вы хотите id сообщения электронной почты в этой функции мыши, а не индекс, например, 0, 12, 32, 5, а не 0, 1, 2, 3.

Учитывая, что (легко настроить с .index(), если предположение неверно), вы можете сделать это:

function CheckForNewMail() { 
    MailInInbox[0] = ["0", "Mail One"]; 
    MailInInbox[1] = ["12", "Mail Two"]; 
    MailInInbox[2] = ["32", "Mail Three"]; 
    MailInInbox[3] = ["5", "Mail Four"]; 
    $('#mail-in-inbox').empty(); 

    var size = 4, element = $('#mail-in-inbox'); 
    for(i = 0; i < size; ++i) { 
     $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>') 
     .data('id', MailInInbox[i][0]).wrap('<li/>').parent().appendTo(element); 
    } 
} 

Есть несколько изменений здесь:

  • массива литералов, много более простая нотация
  • Правило var Объявление о переменных (если они еще не определены в другом месте)
  • Использование .data() для хранения id на <a> мы только что создали

Затем, используя, что сохраненные данные, мы можем прикрепить одного обработчика к #mail-in-inbox контейнера один раз (на DOM готов), а чем один к каждый<a>каждый время работает эта функция, она должна выглядеть следующим образом:

$('#mail-in-inbox').delegate('.inbox-link', 'click', function() { 
    alert("Button "+ $.data(this, 'id') +" clicked!"); 
}); 

Это будет отображаться "Button 0 clicked!", "Button 12 clicked" и т. Д. You can test out all of the above in a demo here.