AJAX addEventListener - передача параметров в другую функцию - PullRequest
1 голос
/ 06 января 2011

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

Вот код:

for (var i in data.contacts) {  
    var temp = document.createElement('div'); 
    temp.className = "contacts"; 
    var dude = document.createElement('input');
    dude.type = "button"; 
    dude.value = data.contacts[i];
    dude.id = data.contacts[i]; 
    dude.className = "dude_button" + data.contacts[i]; 

    dude.addEventListener('click', function(event) { gotoProfile(dude.id); }, false); 


    temp.appendChild(dude); 
    temp.appendChild(document.createElement('br'));
    theDiv.appendChild(temp); 

}
// and now in another file, there's gotoProfile():

function gotoProfile(x) {
var username = document.getElementById(x).value;  

if (xmlHttp) {
    try { 
.... etc.

Теперь это работает, вроде как, но проблема в том, что когда я нажимаю любую кнопку, она пропускает только последнююdude.id значение из списка data.contacts.Очевидно, я хочу, чтобы каждая кнопка addEventListener передавала свое собственное значение data.contacts[i] вместо только последнего.

Помощь оценена, спасибо, ребята.

1 Ответ

3 голосов
/ 06 января 2011

Поскольку JavaScript не имеет области видимости блока, dude будет ссылаться на последний назначенный элемент (поскольку цикл завершен) при вызове обработчика события. Вы должны capture ссылка на текущий dude, например, используя непосредственную функцию:

dude.addEventListener('click', (function(d) {
    return function(event) { 
        gotoProfile(d.id); 
    }
}(dude)), false);

Это распространенная ошибка при создании функций в цикле.


Но вы можете сделать это еще проще. У объекта event есть свойство target, которое указывает на элемент, на котором было возбуждено событие. Так что вы можете просто сделать:

dude.addEventListener('click', function(event) { 
    gotoProfile(event.target.id); 
}, false); 

И с учетом вышесказанного вам не нужно добавлять обработчик для каждой кнопки. Поскольку вы делаете то же самое для каждой кнопки, вы можете прикрепить один и тот же обработчик событий выше к родительскому элементу кнопок (или к общему предку), и он все равно будет работать. Вам просто нужно отфильтровать клики, которые не происходят на кнопке:

parent.addEventListener('click', function(event) { 
    if(event.target.nodeName == 'INPUT' && event.target.type == "button") {
        gotoProfile(event.target.id); 
    }
}, false);
...