J'utilise l'API FileReader pour lire des fichiers en local.
<input type="file" id="filesx" name="filesx[]" onchange="readmultifiles(this.files)" multiple="" />
<script>
function readmultifiles(files) {
var ret = "";
var ul = document.querySelector("#bag>ul");
while (ul.hasChildNodes()) {
ul.removeChild(ul.firstChild);
}
for (var i = 0; i < files.length; i++) //for multiple files
{
var f = files[i];
var name = files[i].name;
alert(name);
var reader = new FileReader();
reader.onload = function(e) {
// get file content
var text = e.target.result;
var li = document.createElement("li");
li.innerHTML = name + "____" + text;
ul.appendChild(li);
}
reader.readAsText(f,"UTF-8");
}
}
</script>
Si l'entrée comprend 2 fichiers:
file1 ---- "content1"
file2 ---- "content2"
Je reçois cette sortie:
file2__content1
file2__content2
Comment réparer le code à afficher:
file1__content1
file2__content2
Le problème est que vous exécutez la boucle maintenant mais les rappels que vous définissez sont exécutés later (lorsque les événements sont déclenchés). Au moment où ils courent, la boucle est terminée et reste à quelle que soit la dernière valeur. Donc, il affichera toujours "fichier2" dans votre cas pour le nom.
La solution consiste à mettre le nom du fichier dans une fermeture avec le reste. Une façon de faire est de créer une expression de fonction immédiatement appelée (IIFE) et de passer le fichier en tant que paramètre à cette fonction:
for (var i = 0; i < files.length; i++) { //for multiple files
(function(file) {
var name = file.name;
var reader = new FileReader();
reader.onload = function(e) {
// get file content
var text = e.target.result;
var li = document.createElement("li");
li.innerHTML = name + "____" + text;
ul.appendChild(li);
}
reader.readAsText(file, "UTF-8");
})(files[i]);
}
Vous pouvez également définir une fonction nommée et l'appeler normalement:
function setupReader(file) {
var name = file.name;
var reader = new FileReader();
reader.onload = function(e) {
// get file content
var text = e.target.result;
var li = document.createElement("li");
li.innerHTML = name + "____" + text;
ul.appendChild(li);
}
reader.readAsText(file, "UTF-8");
}
for (var i = 0; i < files.length; i++) {
setupReader(files[i]);
}
J'ai eu le même problème, résolu en utilisant Array.from
let files = e.target.files || e.dataTransfer.files;
Array.from(files).forEach(file => {
// do whatever
})
Au lieu d'utiliser var , utilisez let car la variable déclarée ne doit être utilisée que dans une boucle.
for (let i = 0; i < files.length; i++) //for multiple files
{
let f = files[i];
let name = files[i].name;
alert(name);
let reader = new FileReader();
reader.onload = function(e) {
// get file content
let text = e.target.result;
let li = document.createElement("li");
li.innerHTML = name + "____" + text;
ul.appendChild(li);
}
reader.readAsText(f,"UTF-8");
}