264 votes

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

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

J'ai essayé plusieurs choses et j'ai cherché sur Google, mais en vain. Le morceau de code suivant ne fonctionne pas comme prévu. Je devrais obtenir la valeur de i sur le clic mais il retourne toujours 6. Je m'arrache les cheveux, aidez-moi s'il vous plaît.

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

    console.log(i);

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

jsfiddle

156voto

Gurpreet Singh Points 5982

Démonstration de travail

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

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

La solution de contournement est d'envelopper cela dans une fonction anonyme et de passer i comme 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);
}

UPDATE

Mise à jour de la DEMO

Ou vous pouvez utiliser "laisser au lieu de var de déclarer i . let vous donne une reliure fraîche à chaque fois. Il ne peut être utilisé qu'avec ECMAScript 6. strict mode .

'use strict';

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

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

39voto

Maloric Points 1507

Le problème est que lorsque vous itérez dans la boucle, i est incrémenté. La valeur finale est de 6. Lorsque vous dites alert(i) vous demandez à javascript de vous dire quelle est la valeur de i es au moment où le lien est cliqué qui, à ce stade, est de 6.

Si vous voulez 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());
  });
}

div {
  display: inline-block;
  width: 15px;
  height: 15px;
  background-color: red;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

18voto

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

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X