Téléchargement de fichiers HTML5 par glisser-déposer. Travailler avec des fichiers téléchargés

Nous continuons à créer notre téléchargement par glisser-déposer, et aujourd'hui nous allons écrire notre serveur et commencer à écrire du code JavaScript.

Dans le dernier article, nous avons écrit un fichier index.html et ses styles. Aujourd'hui, nous allons écrire un serveur qui téléchargera les fichiers et renverra des informations les concernant au script, mais parlons d'abord de la structure de fichiers que nous aurons :

  • .htaccess
  • index.html
  • style.css
  • télécharger.php
  • téléchargements

Tout est clair avec les fichiers index.html et style.css. Nous définissons simplement l'encodage dans le fichier .htaccess pour qu'il n'y ait aucun problème.

AddDefaultCharset UTF-8

Le fichier upload.php téléchargera les fichiers sur le serveur dans le dossier de téléchargement.

Alors commençons par php. Pour ce faire, ouvrez le fichier upload.php et écrivez ce qui suit :

Au début du fichier, nous écrivons un en-tête Content-Type pour indiquer au navigateur qu'il recevra json. Ensuite, nous créons un tableau $uploaded vide et vérifions s'il existe des fichiers. Si oui, nous les parcourons et les téléchargeons dans notre répertoire de téléchargement, et remplissons également notre tableau principal $uploaded avec des sous-tableaux qui contiendront des informations sur les fichiers. Dans notre cas, il s'agit du nom du fichier et de son emplacement. Enfin, nous convertissons notre tableau en json et le produisons. Comme vous pouvez le constater, le serveur n’est pas compliqué du tout.

Passons maintenant au fichier index.html


Déplacez des fichiers ici

(fonction() (
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = fonction() (
this.className = "dragover de zone de dépôt" ;
this.innerHTML = "Lâchez la souris";
renvoie faux ;
};

Dropzone.ondragleave = fonction() (


renvoie faux ;
};

Dropzone.ondrop = fonction(e) (
this.className = "zone de dépôt" ;
this.innerHTML = "Faites glisser les fichiers ici";
e.preventDefault();
};
})();

Vous vous souvenez de la classe .dragover que nous avons écrite dans le dernier article, et j'ai dit qu'elle serait utilisée lorsqu'il y aurait un fichier au-dessus de notre bloc ? C’est en fait ce que nous avons fait maintenant. Lorsqu'un fichier apparaît au-dessus du bloc, l'événement ondragover est déclenché, où nous ajoutons simplement notre classe .dragover et modifions le texte en "Lâchez la souris". Lorsque nous éloignons la souris avec le fichier de notre bloc, l'événement ondragleave est déclenché, où nous remettons tout à sa position d'origine. Lorsqu'une personne « dépose » un fichier dans notre bloc, l'événement ondrop est déclenché. Là, nous modifions tout à nouveau, comme c'était le cas au début, sinon notre classe .dragover « se figera » et annulera le comportement par défaut. Si nous ne le faisons pas, notre fichier s'ouvrira simplement dans le navigateur, ce qui n'est pas ce que nous souhaitons.

Ce balisage n'a rien à voir spécifiquement avec le glisser-déposer. C'est juste un balisage normal, fonctionnel, bien qu'avec quelques éléments HTML supplémentaires pour les états potentiels.

Choisissez un fichier ou faites-le glisser ici. Téléchargement terminé ! Erreur! .

Nous masquerons ces états jusqu'à ce que nous en ayons besoin :

Box__dragndrop, .box__uploading, .box__success, .box__error ( affichage : aucun ; )

Une petite explication :

  • Concernant les états : l'élément .box__uploading sera visible pendant le processus Ajax de téléchargement de fichier (et les autres seront toujours masqués). Ensuite, .box__success ou .box__error sera affiché en fonction de ce qui se passe.
  • l'entrée et l'étiquette sont les parties fonctionnelles du formulaire. J'ai écrit sur leur style ensemble dans mon article sur la personnalisation des entrées de fichiers. Dans cet article, j'ai également décrit le but de l'attribut. L'entrée et l'étiquette servent également d'alternative pour sélectionner des fichiers de la manière standard (ou la seule manière si le glisser-déposer n'est pas pris en charge).
  • .box__dragndrop sera affiché si un navigateur prend en charge la fonctionnalité de téléchargement de fichiers par glisser-déposer.
Détection de fonctionnalités

Nous ne pouvons pas compter à 100 % sur les navigateurs prenant en charge le glisser-déposer. Nous devrions fournir une solution de secours. Et donc : détection de fonctionnalités. Le téléchargement de fichiers par glisser-déposer repose sur un certain nombre d'API JavaScript différentes, nous devrons donc les vérifier toutes.

Tout d’abord, bien sûr, vous devez créer un élément qui « capturera » le fichier. De plus, nous placerons une balise span dans cet élément pour afficher des messages sur l'état de chargement et saisir avec type déposer, afin de ne pas limiter la sélection de fichiers au glisser-déposer, mais également de permettre aux utilisateurs de sélectionner un fichier en cliquant sur cette zone désignée. La forme finale d'une telle structure est présentée ci-dessous.

Cliquez ici ou faites glisser et déposez le fichier à télécharger.

CSS pour ça HTML le code est banal, à l'exception de la conception du champ saisir:

#file( width:100%; height:100%; display:block; position:absolute; top:0; left:0; opacity:0.01; )

Nous décrivons également deux classes qui, lorsqu'elles sont ajoutées à la zone « capture » d'un fichier, signaleront un téléchargement de fichier réussi ou une erreur si une erreur se produit :

#drop-zone.success( couleur-de-fond:#2ecc71; ) #drop-zone.error(couleur-de-fond:#e74c3c; )

Nous pouvons maintenant passer à l’écriture de « l’action » de notre page. Tout d’abord, écrivons dans les variables les références aux objets auxquels nous accéderons assez souvent :

Var dropZone = document.getElementById("drop-zone"); var msgContainer = document.querySelector("#drop-zone .text");

Après cela, nous supprimerons les événements par défaut lorsque le curseur atteint notre zone de réception de fichiers comme suit :

Var eventClear = function (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventClear, false); dropZone.addEventListener("dragover", eventClear, false);

DropZone.addEventListener("drop", function (e) ( if(!e.dataTransfer.files) return; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("file").addEventListener("change", function (e) ( sendFile(e.target.files); ), false);

Dans les deux cas l'événement se termine par un appel de fonction envoyer le fichier, dans lequel est transféré le fichier reçu de l'utilisateur.

Cette fonction est responsable du transfert du fichier vers le serveur. Vous pouvez voir sa description ci-dessous.

Var sendFile = function(file) ( // supprime les classes d'état qui auraient pu être ajoutées // si l'utilisateur a déjà essayé de télécharger quelque chose dropZone.classList.remove("success"); dropZone.classList.remove("error") ; / / nous vérifions à l'aide d'une expression régulière le type de fichier // (dans l'exemple, seules les images peuvent être chargées) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/ i; if (!re. exec(file.name)) ( msgConteiner.innerHTML = "Format de fichier invalide!"; dropZone.classList.remove("success"); dropZone.classList.add("error"); ) else ( var fd = new FormData( ); // création d'un objet de formulaire fd.append("upfile", file); // ajout d'un fichier au formulaire de soumission var xhr = new XMLHttpRequest(); xhr.open("POST" , "./upload.php", true ); xhr.upload.onprogress = showProgress; xhr.onreadystatechange = statChange; xhr.send(fd); // envoi au serveur ) )

Comme vous l'avez peut-être remarqué, avant d'envoyer des données au serveur, deux événements sont également définis, le premier étant chargé d'afficher la progression du téléchargement et le second de notifier le résultat du téléchargement. Ils fonctionnent de la manière suivante :

Var showProgress = function(e) ( if (e.lengthComputable) ( // calculer le pourcentage de chargement var percent = Math.floor((e.loaded / e.total) * 100); // afficher le pourcentage actuel msgConteiner.innerHTML = " Chargement... ("+ pourcentage +"%)"; ) ); var statChange = function (e) ( if (e.target.readyState == 4) ( // à la fin du traitement de la demande au serveur if (e.target.status == 200) ( // si la demande a réussi msgConteiner.innerHTML = "Téléchargement terminé avec succès !"; dropZone.classList.remove("error"); dropZone.classList.add("success"); document.getElementById("showUpFile").innerHTML = this.responseText; ) else ( // sinon msgConteiner.innerHTML = "Une erreur s'est produite!"; dropZone.classList.remove("success"); dropZone.classList.add("error"); ) ) )

La dernière étape consistera à traiter les données reçues par le serveur.

Dans ce tutoriel, nous allons créer un petit formulaire de téléchargement de fichiers AJAX qui permettra aux visiteurs de télécharger des fichiers en utilisant ou en utilisant une sélection de fichiers normale.

Nous utiliserons les plugins jQuery File Upload et jQuery Knob pour afficher le fichier .

Parce que le formulaire pourra télécharger des fichiers de deux manières, il fonctionnera même si le glisser/déposer n'est pas pris en charge.

HTML

Comme d'habitude, commençons par le balisage HTML5 :

Formulaire de téléchargement de fichiers Mini Ajax, déposez-le ici Parcourir

Dans la balise de notre document, nous incluons les polices Google Webfonts, et avant de fermer la balise - les bibliothèques JavaScript : jQuery, jQuery Knob et jQuery File Upload.

L'élément principal de la page est le formulaire #upload. À l'intérieur se trouvent l'élément #drop (accepte les fichiers par glisser-déposer) et une liste dans laquelle les fichiers téléchargés seront affichés. Balisage qui sera généré pour les fichiers téléchargés :

  • Coucher de soleil.jpg 145 Ko

  • L'élément d'entrée sera masqué à l'aide de CSS. Il est nécessaire pour initialiser le plugin jQuery Knob, qui dessinera le fichier. L'entrée a des attributs data-* qui sont utilisés pour mettre à jour l'échelle. Plus tard, lorsque nous suivrons la progression du chargement, nous mettrons à jour ces valeurs pour redessiner l'échelle. span contiendra une coche verte ou une croix rouge.

    jQuery

    Le visiteur aura 2 manières de télécharger le fichier :

    • Faites glisser le fichier dans la fenêtre du navigateur (ne fonctionne pas sous IE).
    • En cliquant sur le bouton Parcourir. Un clic sur l'entrée masquée sera simulé et la fenêtre de sélection du fichier système s'affichera. Notez que l'entrée a un paramètre multiple, ce qui vous permettra de sélectionner plusieurs fichiers à la fois.

    Une fois les fichiers sélectionnés, ils sont mis en file d'attente pour un téléchargement automatique ultérieur :

    $(function())( var ul = $("#upload ul"); $("#drop a").click(function())( // simule un clic sur le champ de sélection de fichier $(this).parent (). find("input").click(); )); // initialise le plugin jQuery File Upload $("#upload").fileupload(( // cet élément acceptera les fichiers déposés dessus dropZone: $( "#drop" ), // La fonction sera appelée lorsque le fichier sera mis en file d'attente add: function (e, data) ( var tpl = $("

  • "); // affiche le nom et la taille du fichier tpl.find("p").text(data.files.name) .append(" " + formatFileSize(data.files.size) + ""); data.context = tpl.appendTo(ul); // initialisation du plugin jQuery Knob tpl.find("input").knob(); // suivi des clics sur l'icône d'annulation tpl.find("span") .click (function())( if(tpl.hasClass("working"))( jqXHR.abort(); ) tpl.fadeOut(function())( tpl.remove(); )); )); // Charger automatiquement le fichier lors de l'ajout à la file d'attente var jqXHR = data.submit(); ), progress: function(e, data)( // Calcul du pourcentage de chargement var progress = parseInt(data.loaded / data.total * 100, 10); // mise à jour de l'échelle data.context.find("input").val(progress).change(); if(progress == 100)( data.context.removeClass("working"); ) ), fail:function(e, data) ( // quelque chose s'est mal passé data.context.addClass("error"); ) )); $(document).on("drop dragover", function (e) ( e.preventDefault( ); )); // fonction d'assistance qui formate la fonction de taille de fichier formatFileSize(bytes) ( if (typeof bytes !== "number") ( return ""; ) if (bytes >= 1000000000) ( return (bytes / 1000000000 ).toFixed(2 ) + "GB" ; ) if (bytes >= 1000000) ( return (bytes / 1000000).toFixed(2) + " MB"; ) return (bytes / 1000).toFixed(2) + " Ko"; ) ));

    jQuery File Upload a sa propre interface, mais nous utilisons la version de base du plugin pour créer notre propre conception d'interface. Et pour que notre interface fonctionne, nous transmettons plusieurs paramètres/callbacks au plugin :

    • dropZone – Ce paramètre contient un sélecteur jQuery qui acceptera les fichiers supprimés. Les fichiers déposés dessus seront ajoutés à la file d'attente de téléchargement.
    • ajouter – la fonction est appelée lorsqu'un fichier est ajouté à la file d'attente de téléchargement. Il générera un balisage pour les fichiers et appellera la méthode data.submit().
    • progression – Cette fonction sera appelée toutes les 100 ms (peut être modifiée). Le deuxième argument contient la taille du fichier et le nombre d'octets téléchargés. Cela vous permet de suivre les progrès et de mettre à jour l’échelle.
    • fail – la fonction est appelée lorsqu’une erreur se produit.
    PHP

    Le kit jQuery File Upload comprend également un script PHP pour traiter les fichiers sur le serveur, mais nous écrirons le nôtre. Le processus de téléchargement des fichiers se déroulera de la même manière que lors d'un téléchargement normal, nous pouvons donc obtenir toutes les informations les concernant à partir du tableau global $_FILES :