Загрузка файлов и каталогов перетаскиванием с помощью drag and drop JS

от автора

На многих веб-сайтах есть форма для загрузки файла. Для некоторых сайтов, таких как OneDrive или Google Диск, загрузка файлов является основной функцией. С течением времени веб-страницы становятся все более интерактивными. Таким образом, пользователи ожидают большего количества взаимодействий, таких как перетаскивание файлов или каталогов или вставка скриншотов.

Давайте посмотрим, что предоставляют браузеры для загрузки файлов!

<form method="post" enctype="multipart/form-data">     <input type="file" name="photo">     <input type="submit" value="Submit"> </form>

Вы можете улучшить это с помощью двух необязательных атрибутов:

  • multiple: позволяет выбрать несколько файлов

  • accept: выберите ожидаемые mime types, например: image/*, application/pdf

Drag and drop файлов

Большинство пользователей ожидают, что смогут перетаскивать файлы на страницу. Эта функциональность хорошо поддерживается браузерами и очень проста в реализации. Как только вы получите файлы, вам нужно что-то сделать, например, загрузить их в API или прочитать их содержимое с помощью FileReader api.

const dropZone = document.body; if (dropZone) {     let hoverClassName = 'hover';        dropZone.addEventListener("dragenter", function(e) {         e.preventDefault();         dropZone.classList.add(hoverClassName);     });        dropZone.addEventListener("dragover", function(e) {         e.preventDefault();         dropZone.classList.add(hoverClassName);     });        dropZone.addEventListener("dragleave", function(e) {         e.preventDefault();         dropZone.classList.remove(hoverClassName);     });        // Это самое важное событие, событие, которое дает доступ к файлам     dropZone.addEventListener("drop", function(e) {         e.preventDefault();         dropZone.classList.remove(hoverClassName);          const files = Array.from(e.dataTransfer.files);         console.log(files);         // TODO что-то делает с файлами...     }); }

Вы можете легко загружать файлы в API, используя fetch API:

if (files.length > 0) {     const data = new FormData();     for (const file of files) {         data.append('file', file);     }      fetch('/upload', {         method: 'POST',         body: data     })     .then(() => console.log("file uploaded"))     .catch(reason => console.error(reason)); }

Drag and drop директорий

Google Chrome и Microsoft Edge теперь поддерживают перетаскивание каталогов. Это очень полезно, если вы хотите загрузить свои файлы в OneDrive или Google Диск. API не очень удобен, так как использует функции обратного вызова с рекурсивным деревом, но это не так сложно. Давайте посмотрим на какой-нибудь код:

// drag* события опущены для краткости (получите их из предыдущего раздела). dropZone.addEventListener('drop', async function(e) {     e.preventDefault();     dropZone.classList.remove(hoverClassName);      console.log(await getFileAsync(e.dataTransfer)); };  async function getFileAsync(dataTranfer) {     const files = [];     for (var i = 0; i < dataTranfer.items.length; i++) {         const item = dataTranfer.items[i];         if (item.kind === 'file') {             if (typeof item.webkitGetAsEntry === 'function'){                 const entry = item.webkitGetAsEntry();                 const entryContent = await readEntryContentAsync(entry);                 files.push(...entryContent);                 continue;             }              const file = item.getAsFile();             if (file) { files.push(file); }         }     }     return files; };  // Возвращает Promise со всеми файлами иерархии каталогов function readEntryContentAsync(entry) {     return new Promise((resolve, reject) => {         let reading = 0;         const contents = [];          readEntry(entry);          function readEntry(entry) {             if (entry.isFile) {                 reading++;                 entry.file(file => {                     reading--;                     contents.push(file);                      if (reading === 0) {                         resolve(contents);                     }                 });             } else if (entry.isDirectory) {                 readReaderContent(entry.createReader());             }         };                function readReaderContent(reader) {             reading++;             reader.readEntries(function(entries) {                 reading--;                 for (const entry of entries) {                     readEntry(entry);                 }                 if (reading === 0) {                     resolve(contents);                 }             });         };     }); };

Теперь вы мастера загружать файлы и каталоги.


ссылка на оригинал статьи https://habr.com/ru/articles/752268/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *