Tengo este código que te permite cargar varias imágenes y obtener una vista previa. También quiero obtener el nombre de las imágenes y su tamaño. Solo funciona mientras subes solo una imagen. Si carga más de una, las propiedades de la imagen serán las mismas para cada imagen. (Obtendrán las últimas informaciones).
Creo que el problema está en la función picReader, porque falla con el bucle for. ¿Alguna idea de cómo suela?
Lo que quiero: quiero obtener el file.name que es el nombre de la imagen (por ejemplo, ejemplo.jpg) y el file.size que es el tamaño de la imagen (por ejemplo: 181135) para cada imagen una por una con sus propias informaciones. Pero ahora, mostrará la misma información para cada imagen (= Mostrará la información de la última imagen para las demás también).
function handleFileSelect() { if (window.File && window.FileList && window.FileReader) { document.getElementById('result').textContent = ''; var files = event.target.files; //FileList object var output = document.getElementById("result"); for (var i = 0; i < files.length; i++) { var file = files[i]; if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", function (event) { var picFile = event.target; var div = document.createElement("div"); div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" + "title='" + picFile.name + "'/>"; console.log(file.name+'::'+file.size); output.insertBefore(div, null); }); picReader.readAsDataURL(file); } } else { console.log("Your browser does not support File API"); } } document.getElementById('files').addEventListener('change', handleFileSelect, false); body { font-family:'Segoe UI'; font-size: 12pt; } header h1 { font-size:12pt; color: #fff; background-color: #F39C12; padding: 20px; } article { width: 80%; margin:auto; margin-top:10px; } .thumbnail { height: 100px; margin: 10px; } output { display: flex; } <article> <label for="files">Select multiple files:</label> <input id="files" type="file" multiple="multiple" /> <output id="result" /> </article>El problema es que i , dentro de todas las funciones anónimas que pasa como detector de eventos de carga, tiene la misma variable fuera de la función, lo que hace que la variable del file sea la misma para todas las iteraciones también.
Tienes 3 opciones aquí:
ES6 : si usa ES6, puede usar let en lugar de var . Cada iteración del ciclo con un índice let , tiene una nueva variable i :
for (let i = 0; i < files.length; i++) { let file = files[i]; if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", function (event) { var picFile = event.target; var div = document.createElement("div"); div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" + "title='" + picFile.name + "'/>"; console.log(file.name+'::'+file.size); output.insertBefore(div, null); }); picReader.readAsDataURL(file); } para forEach método:
files.forEach(function(file) { if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", function (event) { var picFile = event.target; var div = document.createElement("div"); div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" + "title='" + picFile.name + "'/>"; console.log(file.name+'::'+file.size); output.insertBefore(div, null); }); picReader.readAsDataURL(file); })Una función que crea otra función : con esta solución, vincularía la variable dentro de cada función a un valor que no cambia:
for (let i = 0; i < files.length; i++) { let file = files[i]; if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", createFunc(i, files)); picReader.readAsDataURL(file); } function createfunc(i, files) { return function(event) { var file = files[i]; var picFile = event.target; var div = document.createElement("div"); div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" + "title='" + picFile.name + "'/>"; console.log(file.name+'::'+file.size); output.insertBefore(div, null); }); }