web-dev-qa-db-fra.com

Le gestionnaire de clics JavaScript ne fonctionne pas comme prévu dans une boucle for

J'essaie d'apprendre JS et j'ai un problème.

J'ai essayé beaucoup de choses et googlé mais tout en vain. Le morceau de code suivant ne fonctionne pas comme prévu. Je devrais obtenir la valeur de i au clic, mais cela renvoie toujours 6. J'arrache mes cheveux., Aidez-moi.

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

    console.log(i);

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

jsfiddle

228
JS-coder

DEMO de travail

Il s'agit d'un problème de fermeture JavaScript classique. La référence à l'objet i est stockée dans la fermeture du gestionnaire de clics, plutôt que la valeur réelle de i.

Chaque gestionnaire de clic fera référence au même objet, car il n'y a qu'un seul objet compteur qui en contient 6, vous obtenez donc six à chaque clic.

La solution de contournement consiste à envelopper cela dans une fonction anonyme et à passer i en argument. Les primitives sont copiées par valeur dans les appels de fonction.

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

[~ # ~] mise à jour [~ # ~]

DEMO mise à jour

Ou vous pouvez utiliser 'let' à la place var pour déclarer i. let vous offre une nouvelle liaison à chaque fois. Il ne peut être utilisé que dans ECMAScript 6 strict mode.

'use strict';

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

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

Le problème est que lorsque vous parcourez la boucle, i est incrémenté. Il se termine par une valeur de 6. Lorsque vous dites alert(i) vous demandez à javascript de vous indiquer la valeur de i au moment où le lien est cliqué , qui par ce point est 6.

Si vous souhaitez obtenir le contenu de la boîte à la place, vous pouvez faire quelque chose comme ceci:

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

    console.log(i);

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

Exemple de travail: http://jsfiddle.net/rmXcF/2/

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

C'est parce qu'il utilise la valeur de i comme fermeture. i est mémorisé grâce à une fermeture qui augmente à chaque étape de la boucle du plancher.

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