Cas simple: je souhaite charger plusieurs images qui ont un nom commun et un suffixe, par exemple: image0.png, image1.png, image2.png … imageN.png
J'utilise une boucle simple pour:
var images = []; for (var i=1; i<N; i++) { images[i] = new Image(); images[i].onload = function () { console.log("Image " + i + " loaded"); }; images[i].src = "image" + i + ".png"; }
Ce que je reçois dans la console est:
Image N loaded Image N loaded Image N loaded ... Image N loaded
Mais ce que je veux, c'est comme ceci:
Image 0 loaded Image 1 loaded Image 2 loaded ... Image N loaded
Pourquoi cela arrive-t-il? Comment puis-je obtenir mon comportement désiré?
Le i
dans votre fonction est évalué lorsque la fonction est exécutée , et non pas lorsque vous l'affectez à la charge. Votre boucle for a déjà terminée au moment où toutes les fonctions de votre charge sont onload
, de sorte que toutes voyez la valeur finale N
Pour capturer la valeur actuelle de i
, vous devez la passer comme paramètre à une autre fonction où elle peut être captée en tant que variable locale:
function captureI(i) { return function () { console.log("Image " + i + " loaded"); }; } var images = []; for (var i=1; i<N; i++) { images[i] = new Image(); images[i].onload = captureI(i); images[i].src = "image" + i + ".png"; }
Cela fonctionne car chaque fois que vous appelez captureI
, une nouvelle variable locale est créée pour cette instance de captureI
. Essentiellement, vous créez N
variables différentes et chaque fonction onload
capture une instance différente de la variable.
Vous pouvez l'envelopper dans une fermeture pour éviter d'utiliser la variable i
, ce qui est une variable de boucle et modifie donc:
(function(j) { images[i].onload = function () { console.log("Image " + i + ", " + j + " loaded"); }; })(i);
Cela démontre la différence entre i
, qui est une variable de boucle et change, et j
, qui est un paramètre lié à la fonction, qui ne change pas.
Voir le jsfiddle ici:
Votre variable de compteur de boucle a déjà été écrasée. Consultez cette rubrique FAQ expliquant exactement pourquoi il se passe et comment contourner ce problème.
Comme la variable i
est déclarée hors du cadre de la boucle, elle conserve sa valeur finale après la fin de la boucle. Les fonctions anonymes que vous créez, alors toutes se lient à cette variable, et lorsqu'elles sont appelées, elles obtiennent toutes la même valeur finale de N
Il y a une bonne discussion dans cette question .