Инструментът за обработка на кликвания на JavaScript не работи според очакванията в for цикъл

Опитвам се да науча JS и имам проблем.

Опитах много неща и търсих в Google, но всичко беше напразно. Следната част от кода не работи според очакванията. Трябва да получа стойност 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 се запомня чрез затваряне, което се увеличава на всеки етап от долния контур.

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