Précisions sur le fichier drag
/drop
en HTML5
J'ai fait quelques recherches dans de nombreuses documentations pour ce sujet et testé par moi-même sur les différents navigateurs, c'est pourquoi j'ai décidé de résumer tout ce que je sais à propos de faire glisser et déposer des fichiers ici.
Glisser:
Lorsque vous faites glisser un fichier, vous pouvez utiliser certains auditeurs, tels que:
dragenter
dragover
dragend
dragleave
Étant donné que ce sont des drag
événements, l' files
de la propriété de l' event.dataTransfer
ont length == 0
ou être vide (null
). Donc vous ne pouvez pas lire les fichiers détails d'un événement glisser et vous ne pouvez pas vérifier s'ils sont les dossiers. Ce n'est pas un bug, c'est une mesure de sécurité. Imaginez que vous pouvez lire des fichiers sur un événement glisser: vous seriez capable de tout lire même si l'utilisateur ne veut pas télécharger des fichiers sur votre site. Il n'aurait aucun sens, au sérieux. Imaginez que vous faites glisser un fichier à partir de votre bureau à un autre dossier et que vous faites accidentellement glisser au travers d'une page web: la page web de lit de votre fichier et stocke vos informations personnelles sur son serveur... ce serait une grande confidentialité et la sécurité de la faute.
Toutefois, vous serez toujours en mesure de détecter si vous êtes déposer des fichiers par itération sur le tableau event.dataTransfer.types
. Vous pouvez créer une fonction qui vérifie si l'événement glisser contient des fichiers, puis l'appeler dans le gestionnaire d'événements.
Exemple:
function containsFiles(event) {
if (event.dataTransfer.types) {
for (var i=0; i<event.dataTransfer.types.length; i++) {
if (event.dataTransfer.types[i] == "Files") {
return true;
}
}
}
return false;
}
function handleDragEnter(e) {
e.preventDefault();
if containsFiles(e) {
// The drag event contains files
// Do something
} else {
// The drag event doesn't contain files
// Do something else
}
}
Déposer:
Lorsque vous déposez un fichier dans la baisse de la div, vous utilisez un écouteur pour l'événement drop
pour lire un fichier de propriétés telles que le nom, la taille, le type et la date de dernière modification.
Pour détecter si un fichier est un dossier, vous allez:
- Vérifiez si le fichier a
type == ""
, parce que les dossiers ont pas de type.
- Vérifier si la taille du fichier est un multiple de 4096:
size%4096 == 0
, parce que les dossiers ont toujours une taille multiple de 4096 octets (ce qui est 4KiB).
Exemple:
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) { // iterate in the files dropped
if (!f.type && f.size%4096 == 0) {
// The file is a folder
// Do something
} else {
// The file is not a folder
// Do something else
}
}
}
PROBLÈME CONNU: Depuis que les dossiers sont en fait des fichiers, c'est la seule façon de les distinguer d'un autre type de fichier. Bien que cette méthode ne vous donne pas la certitude absolue qu'un fichier est un dossier: il est peut-être un fichier sans extension et avec une taille de 0 ou N x 4096bytes.
Exemples:
Voici quelques exemples pour expliquer ce que j'ai dit ci-dessus: