Bonjour, je souhaite créer un preloader de ressources en JavaScript permettant de précharger Images, JSON, et sons et pouvoir y accéder. Cependant je rencontre des problèmes qui me paraissent impossible à résoudre:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | function Loader(arr, fn) { this.requiredFiles = arr; // liste des fichiers requis this.loadedFiles = []; // liste des fichiers téléchargés this.files = {}; // objet stoquant les fichiers téléchargés, permet de les rendre accessible this.fn = fn; //fonction de callback s'executtant dès que tout est téléchargé } Loader.prototype.load = function () { var i = 0; while (i < this.requiredFiles.length) { i++; switch (this.requiredFiles[i].type) { case "image": var img = new Image(); //dès que l'image est chargée img.addEventListener('load', function (e) { this.loadedFiles.push(img); // dis que le fichier est chargé this.files[this.requiredFiles[i].key] = img; //rend le fichier accessible sous sa clé, via getFile(key) //Si tout est chargé, le callback s'execute if (this.requiredFiles.length === this.loadedFiles.length) { this.fn(); } }.bind(this), false); img.src = this.requiredFiles[i].file; // déclaration de l'image break; case "json": var xhr = new XMLHttpRequest(); xhr.open('GET', this.requiredFiles[i].file); //dès que le json est chargé xhr.addEventListener('readystatechange', function () { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { this.loadedFiles.push(this.requiredFiles[i].file); //dis que le fichier est chargé var jsonfile = JSON.parse(xhr.responseText); //parse le JSON en objet JS this.files[this.requiredFiles[i].key] = jsonfile; //rend le fichier accessible sous sa clé via getFile(key) //Si tout est chargé, le callback s'execute if (this.requiredFiles.length === this.loadedFiles.length) { this.fn(); } } }.bind(this), false); xhr.send(); break; case "sound": // à remplir break; } } } Loader.prototype.getFile = function (key) { return this.files[key]; //renvoi le fichier en fonction de sa clé } //retourne en pourcentage les fichiers déjà chargés Loader.prototype.getDownloadState = function () { return this.loadedFiles.length / this.requiredFiles.length * 100; } //déclaration des fichiers à charger, de leur clé et leur type var myfiles = new Loader( [ { file: 'jacky.json', key: 'jacky', type: 'json' }, { file: 'jeanmi.json', key: 'jeanmi', type: 'json' }, { file: '/images/tileset.png', key: 'tileset', type: 'image' }, { file: '/images/characters.png', key: 'characters', type: 'image' } ], function () { alert("Tout est chargé!"); //Callback } ); myfiles.load(); //on lance le chargement |
Le problème se situe au niveau des évènements: Quand un fichier est chargé, on le rend accessible en le poussant dans files {} grâce à l'itérateur i: this.files[this.requiredFiles[i].key] = jsonfile; Mais quand le fichier est finalement chargé et que le code dans addEventListener s’exécute, la boucle a déjà avancé et i ne correspond plus au bon fichier. J'ai donc des
1 | this.requiredFiles[i] is undefinied |
Quelqu'un a une idée pour éviter ce fâcheux problème ? Merci d'avance
+0
-0