11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Étant tous nouveau en javascript, j'essaie de faire un aperçu d'image, avant l'upload sur un serveur.
J'ai trouver un tuto : https://openclassrooms.com/courses/dynamisez-vos-sites-web-avec-javascript/l-api-file

J'ai essayé de l'améliorer mais sans succès.
Juste les images se créé dans l'ordre avec leurs noms.
Tous se passe bien si on appuis sur le bouton une fois.
Si on se trompe et que l'on veux réimporter des images, tous part en vrille.
Les images se multiplie autant de fois qu'on appuie sur le bouton.
Si quelqu'un trouve la réponse je suis preneur.

Merci d'avance.


// fonction efface images et noms images
function effaceElements(element) {
	while (element.firstChild) {
		element.removeChild(element.firstChild);
	}
}

// fonction création d'image 
function createThumbnail(file, prev2, i) {
	if (prev2.getElementsByTagName('img').length == i) {
		var reader = new FileReader();
		reader.addEventListener('load', function() {
			var imgElement = document.createElement('img');
			imgElement.style.maxWidth = '150px';
			imgElement.style.maxHeight = '150px';
			imgElement.src = this.result;
			prev.appendChild(imgElement);
		});
		reader.readAsDataURL(file);
	}
	else {
		var timer = setTimeout(function(){createThumbnail(file, prev2, i);}, 250);
	}
}

var allowedTypes = ['png', 'jpg', 'jpeg', 'gif'];
var fileInput = document.querySelector('#AlbumA'); // sélectionne input avec les images
var prev = document.querySelector('#prev'); // sélectionne la div de l'aperçu des images
var prev2 = document.getElementById("prev"); // sélectionne la div de l'aperçu des images
var listof = document.getElementById("listof"); // sélectionne la div des noms d'images
		
effaceElements(prev2);
effaceElements(listof);
		
// envoie d'une image input dans fonction pour création d'image 
fileInput.addEventListener('change', function() {
	var nomFiles = [];
	var files = this.files;
	var filesLen = files.length;
	var imgType;
			
	for (var i = 0; i < filesLen; i++) {
		nomFiles.push(files[i].name);
		imgType = files[i].name.split('.');
		imgType = imgType[imgType.length - 1];
		if (allowedTypes.indexOf(imgType) != -1) {
			createThumbnail(files[i], prev2, i);
		}
	}
	var noms = nomFiles.join(" / ");
	listof.innerHTML = '<p class="nomImport">Il y a '+filesLen+' fichier(s)<br/>'+noms+'</p>';
});
Après plusieurs recherche je pense que le problème viens soit du :
- document.createElement('img')
- reader.readAsDataURL(file);

L'action doit être gardé en mémoire quelque part.
J'ai fait plusieurs test mais sans succès.

Je reviens vers vous si je trouve quelque choses de plus concret.
Je n'abandonne pas. Quelqu'un pourrait être intéressé par le bout de code.
Qui sait ^^.
J'ai trouvé la solution même si je n'ai pas très bien compris le pourquoi.

Apparemment je devais faire appelle à ma fonction "miniature" par un "addEventListener" mettre "event" en "change" avec "useCapture" à false. Si je veux avoir plusieurs formulaires d’envois sur la même page.

Je ne sait pas si ma solution est bien, vue que je commence à coder en javascript.
Il me reste encore un problème quand on appuis sur le bouton trop de fois.

pour visualiser se que ça donne :
http://www.jjbidot.fr/0-Test/

Je vous met le code (sans le css) :


<div id="content">
     <form action="#" method="POST" enctype="multipart/form-data">
          <input type="file" name="Album[]" id="Album" multiple="multiple" onmousedown="return false" onkeydown="return false" />
          <div id="prev"></div>
     </form>
</div>




/*  Effet afficher image avant upload */	
function miniature(fileInput, prev) {
		
     function creationImage(file, prev, i) {
          if (prev.getElementsByTagName('img').length == i) {
               function creationBalise() {
                    var imgElement = document.createElement('img');
                    imgElement.style.maxWidth = '150px';
                    imgElement.style.maxHeight = '150px';
                    imgElement.src = this.result;
                    prev.appendChild(imgElement);
               }
               var reader = new FileReader();
               reader.addEventListener('load', creationBalise);
               reader.readAsDataURL(file);
          }
          else {
               var timer = setTimeout(function(){creationImage(file, prev, i);}, 250);
          }
     }
		
     var allowedTypes = ['png', 'jpg', 'jpeg', 'gif'];
     var nomFiles = [];
     var files = fileInput.files;
     var filesLen = files.length;
     var imgType;
		
     for (var i = 0; i < filesLen; i++) {
          nomFiles.push(files[i].name);
          imgType = files[i].name.split('.');
          imgType = imgType[imgType.length - 1];
          if (allowedTypes.indexOf(imgType) != -1) {
               creationImage(files[i], prev, i);
          }
     }
		
     var noms = nomFiles.join(" / ");
     prev.innerHTML = '<p>Il y a '+filesLen+' fichier(s)<br/>'+noms+'</p>';
		
}
	
document.getElementById('Album').addEventListener('change', function(){
     var fileInput = document.getElementById('Album');
     var prev = document.getElementById('prev');
     miniature(fileInput, prev);	
}, false);
	
/* Fin Effet afficher image avant upload */	

Meilleure solution