Obsługa kliknięć JavaScript nie działa zgodnie z oczekiwaniami wewnątrz pętli for [duplikat]

To pytanie ma już odpowiedź tutaj:

Próbuję nauczyć się JS i mam problem. Próbowałem wielu rzeczy i wygooglowałem, ale wszystko na próżno. Następujący fragment kodu nie działa zgodnie z oczekiwaniami. Powinienem dostać wartość i na kliknięcie, ale zawsze zwraca 6. Wyrywam włosy., proszę pomocy.
for (var i = 1; i < 6; i++) {

    console.log(i);

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

Jsfiddle

Author: Talha Awan, 2013-05-16

3 answers

Demo robocze

Jest to klasyczny problem z zamknięciem JavaScript. Odniesienie do obiektu i jest przechowywane w zamknięciu obsługi kliknięć, zamiast rzeczywistej wartości i.

Każda obsługa pojedynczego kliknięcia będzie odnosić się do tego samego obiektu, ponieważ jest tylko jeden obiekt licznika, który zawiera 6, więc otrzymujesz 6 za każde kliknięcie.

Obejściem jest zawinięcie tego w funkcję anonimową i podanie i jako argumentu. Prymitywy są kopiowane przez wartość w funkcji telefony.

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

UPDATE

Zaktualizowane DEMO

Lub możesz użyć 'let' zamiast var do zadeklarowania i. let daje ci nowe Wiązanie za każdym razem. Można go używać tylko w ECMAScript 6 strict mode.

'use strict';

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

        $("#div" + i).click(
            function () { alert(i); }
        );
 }
 91
Author: Gurpreet Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 10:18:39

Problem polega na tym, że podczas iteracji przez pętlę, i jest zwiększana. Kończy się wartością 6. Kiedy mówisz alert(i), prosisz javascript, aby powiedział ci, jaka jest wartość i w momencie kliknięcia łącza , która w tym punkcie wynosi 6.

Jeśli chcesz zamiast tego pobrać zawartość pudełka, możesz zrobić coś takiego:

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

    console.log(i);

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

Przykład roboczy: http://jsfiddle.net/rmXcF/2/

 21
Author: Maloric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-26 10:33:08
$("#div" + i).click(
    function() {
        alert(i);
    }
);

To dlatego, że używa wartości i jako zamknięcia. i jest zapamiętywany przez zamknięcie, które zwiększa się na każdym etapie pętli foor.

$("#div" + i).click(function(event) {
    alert($(event.target).attr("id").replace(/div/g, ""));
});
 9
Author: flavian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 04:09:30