Подтвердить что ты не робот

Обработчики событий внутри цикла Javascript - нужно закрыть?

Я работаю с небольшим количеством HTML-кода и Javascript-кода, которые я взял с кем-то другим. Страница перезагружает таблицу данных (через асинхронный запрос) каждые десять секунд, а затем повторно строит таблицу с использованием некоторого кода DOM. Этот код выглядит примерно так:

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function() {
        onStatusChanged(select, callid, anotherid);
    };
    td.appendChild(select);
}

Если событие onchange запущено для элемента <select>, однако, похоже, что те же значения передаются методу onStatusChanged() для каждого <select> в таблице (я проверил, что в каждом итерации цикла, callid и anotherid даются новые, отличные значения).

Я подозреваю, что это происходит из-за того, как я устанавливаю обработчик событий с синтаксисом select.onchange = function(). Если я понимаю, как это работает правильно, этот синтаксис устанавливает замыкание для события onchange как функцию, которая ссылается на эти две ссылки, которые в конечном итоге имеют конечное значение того, на что они установлены, на последней итерации цикла. Когда событие срабатывает, значение, на которое ссылаются callid и anotherid, - это значение, установленное в последней итерации, а не значение, заданное на отдельной итерации.

Есть ли способ, которым я могу скопировать значение параметров, которые я передаю, в onStatusChanged()?

Я изменил название, чтобы лучше отразить вопрос и принятый ответ.

4b9b3361

Ответ 1

Вам действительно нужно выполнить закрытие здесь. Это должно работать (дайте мне знать - я его не тестировал)

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function(s,c,a)
    {
        return function()
        {
            onStatusChanged(s,c,a);
        }
    }(select, callid, anotherid);
    td.appendChild(select);
}