Обработчик кликов JavaScript не работает должным образом внутри цикла for

Я пытаюсь изучить JS, но возникла проблема.

Я много чего пробовал и гуглил, но все тщетно. Следующий фрагмент кода работает не так, как ожидалось. При щелчке я должен получить значение i, но оно всегда возвращает 6. Я выдергиваю волосы; пожалуйста помоги.

for (var i = 1; i < 6; i++) {

    console.log(i);

    $("#div" + i).click(
        function() {
            alert(i);
        }
    );
}

jsfiddle


person JS-coder    schedule 16.05.2013    source источник
comment
Вы имеете дело с закрытием: stackoverflow.com/questions / 111102 /   -  person ajm    schedule 16.05.2013


Ответы (3)


Рабочий ДЕМО

Это классическая проблема закрытия JavaScript. Ссылка на объект i сохраняется в закрытии обработчика кликов, а не в фактическом значении i.

Каждый обработчик кликов будет ссылаться на один и тот же объект, потому что есть только один объект счетчика, который содержит 6, так что вы получаете шесть при каждом щелчке.

Обходной путь - обернуть это анонимной функцией и передать i в качестве аргумента. Примитивы копируются по значению в вызовах функций.

for(var i=1; i<6; i++) {
     (function (i) {
        $("#div" + i).click(
            function () { alert(i); }
        );
     })(i);
}

ОБНОВЛЕНИЕ

Обновленная ДЕМО

Или вы можете использовать 'let' вместо var объявить i. let каждый раз выдает новую привязку. Его можно использовать только в ECMAScript 6 strict mode.

'use strict';

for(let i=1; i<6; i++) {

        $("#div" + i).click(
            function () { alert(i); }
        );
 }
person Gurpreet Singh    schedule 16.05.2013

Проблема в том, что по мере прохождения цикла i увеличивается. В итоге получается значение 6. Когда вы говорите alert(i), вы просите javascript сообщить вам, какое значение i равно в момент щелчка по ссылке, которое к этому моменту равно 6.

Если вы хотите получить содержимое коробки, вы можете сделать что-то вроде этого:

for (var i = 1; i < 6; i++) {

    console.log(i);

    $("#div" + i).click(function(e) {
        alert($(this).text());
    });
}

Рабочий пример: http://jsfiddle.net/rmXcF/2/

person Maloric    schedule 16.05.2013
comment
спасибо за объяснение во время перехода по ссылке - person Josh Broadhurst; 02.08.2018

$("#div" + i).click(
    function() {
        alert(i);
    }
);

Это потому, что в качестве закрытия используется значение i. i запоминается через закрытие, которое увеличивается на каждом этапе цикла foor.

$("#div" + i).click(function(event) {
    alert($(event.target).attr("id").replace(/div/g, ""));
});
person flavian    schedule 16.05.2013