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);
}
);
}
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 [~ # ~]
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); }
);
}
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/
$("#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, ""));
});