От автора: возможность загрузки файлов является ключевым требованием для многих веб- и мобильных приложений. От загрузки фотографии в социальные сети до публикации резюме на веб-сайте портала о вакансиях file upload — везде. Как веб-разработчики, мы должны знать, что HTML обеспечивает нативную поддержку загрузки файлов с небольшой помощью JavaScript.
С помощью HTML5FileAPI добавляется в DOM. Используя это, мы можем внутри его прочитать FileList и FileObject. Это дает несколько вариантов использования файлов, их можно загружать локально или отправлять на сервер по сети для обработки, и так далее.
В этой статье мы обсудим 10 таких случаев использования поддержки загрузки файлов HTML. Надеюсь, что вы найдете ее полезной. В любой момент, если вы захотите поэкспериментировать с этими функциями file upload, вы можете найти их здесь.
Исходный код демонстрации находится в моем репозитории Github. Вы можете следить за ним, поскольку я постоянно обновляю код с примерами. Поставьте звездочку, если вы сочтете это полезным.
1. Простая загрузка файла.
Мы можем указать тип поля ввода file, чтобы использовать функционал загрузчика файлов в веб-приложении.
1 |
<input type="file" id="file-uploader"> |
Тип поля ввода file позволяет пользователям с помощью кнопки загружать один или несколько файлов. По умолчанию он позволяет загружать один файл с помощью операционной системы.
При успешной загрузке File API позволяет прочитать Fileobject с помощью простого кода JavaScript. Чтобы прочитать Fileobject, нам нужно получить ответ от команды change в загрузчике файлов. Сначала получите загрузчик файлов по идентификатору.
1 |
const fileUploader = document.getElementById('file-uploader'); |
Затем добавьте прослушиватель событий change для чтения файла после завершения загрузки. Мы получаем информацию о загруженном файле из свойства event.target.files.
1 2 3 4 |
fileUploader.addEventListener('change', (event) => { const files = event.target.files; console.log('files', files); }); |
Рассмотрим ответ в консоли браузера. Обратите внимание на массив FileList с объектом File, который содержит всю информацию о метаданных загруженного файла.
Вот CodePen для вас с тем же примером для дальнейшего изучения.
2. Загрузка нескольких файлов
Мы можем загружать несколько файлов за раз. Для этого нам просто нужно добавить атрибут с именем multiple, к тегу input.
1 |
<input type="file" id="file-uploader" multiple /> |
Теперь файловый браузер позволит вам загрузить один или несколько файлов для загрузки. Как и в предыдущем примере, вы можете добавить обработчик событий change для сбора информации о загруженных файлах. Вы заметили, что FileList это массив? Правильно, для multiple загрузки файлов в массиве будет следующая информация.
Вот ссылка CodePen, чтобы изучить загрузку нескольких файлов.
3. Информация о метаданных файлов.
Каждый раз, когда мы загружаем файл, объект File содержит информацию о метаданных, такую как имя файла, размер, время последнего обновления, типы т. д. Эта информация может быть полезна для дальнейших проверок и принятия решений.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Get the file uploader by id const fileUploader = document.getElementById('file-uploader'); // Listen to the change event and read metadata fileUploader.addEventListener('change', (event) => { // Get the FileList array const files = event.target.files; // Loop through the files and get metadata for (const file of files) { const name = file.name; const type = file.type ? file.type: 'NA'; const size = file.size; const lastModified = file.lastModified; console.log({ file, name, type, size, lastModified }); } }); |
Вот результат для загрузки одного файла.
Используйте этот CodePen для дальнейшего изучения.
4. Свойства accept
Мы можем использовать атрибут accept, чтобы ограничить тип файлов для загрузки. Вы можете отображать только разрешенные типы изображений для просмотра, когда пользователь загружает изображение профиля.
1 |
<input type="file" id="file-uploader" accept=".jpg, .png" multiple> |
В приведенном выше коде файловый браузер разрешает только файлы с расширением jpg и png. Обратите внимание: в этом случае файловый браузер автоматически устанавливает тип выбора файла как пользовательский, а не все. Однако при необходимости вы всегда можете вернуться обратно ко всем файлам.
Используйте этот CodePen, чтобы изучить атрибут accept.
5. Управление содержимым файла.
Вы можете захотеть показать содержимое файла после его успешной загрузки. Что касается изображений профиля, это будет сбивать с толку, если мы не покажем загруженное изображение пользователю сразу после загрузки. Мы можем использовать объект FileReader для преобразования файла в двоичную строку. Затем добавьте прослушиватель событий load, чтобы получить двоичную строку при успешной загрузке файла.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Get the instance of the FileReader const reader = new FileReader(); fileUploader.addEventListener('change', (event) => { const files = event.target.files; const file = files[0]; // Get the file object after upload and read the // data as URL binary string reader.readAsDataURL(file); // Once loaded, do something with the string reader.addEventListener('load', (event) => { // Here we are creating an image tag and adding // an image to it. const img = document.createElement('img'); imageGrid.appendChild(img); img.src = event.target.result; img.alt = file.name; }); }); |
Попробуйте выбрать файл изображения в CodePen ниже и посмотрите, как он отображается.
6. Проверка размера файла.
Как мы видели, мы можем читать метаданные размера файла, мы можем фактически использовать их для проверки размера файла. Вы можете разрешить пользователям загружать изображения размером до 1МБ. Посмотрим, как этого добиться.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Listener for file upload change event fileUploader.addEventListener('change', (event) => { // Read the file size const file = event.target.files[0]; const size = file.size; let msg = ''; // Check if the file size is bigger than 1MB and prepare a message. if (size > 1024 * 1024) { msg = `<span style="color:red;">The allowed file size is 1MB. The file you are trying to upload is of ${returnFileSize(size)}</span>`; } else { msg = `<span style="color:green;"> A ${returnFileSize(size)} file has been uploaded successfully. </span>`; } // Show the message to the user feedback.innerHTML = msg; }); |
Попробуйте загрузить файл разного размера, чтобы увидеть, как работает проверка, ссылка на codepen:
7. Показать прогресс загрузки файла
Для юзабилити полезно сообщить вашим пользователям о процессе загрузки файла. Теперь мы знаем о событии FileReader и событии для чтения и загрузки файла.
1 |
const reader = new FileReader(); |
В FileReader вызывается еще событие под названием progress, чтобы узнать, сколько было загружено. Мы можем использовать тег HTML5 progress для создания индикатора выполнения с этой информацией.
1 2 3 4 5 6 7 8 |
reader.addEventListener('progress', (event) => { if (event.loaded && event.total) { // Calculate the percentage completed const percent = (event.loaded / event.total) * 100; // Set the value to the progress component progress.value = percent; } }); |
Как насчет того, чтобы попробовать загрузить файл большего размера и увидеть, как индикатор выполнения работает в CodePen ниже? Попробуйте демо-версию:
8. Как насчет загрузки каталога?
Можем ли мы загрузить весь каталог? Что ж, это возможно, но с некоторыми ограничениями. Существует нестандартный атрибут (по крайней мере, на момент написания статьи) webkitdirectory который позволяет нам выгружать каталог целиком.
Хотя изначально он был реализован только для браузеров на основе WebKit, webkitdirectory также можно использовать в Microsoft Edge, а также в Firefox 5.0 и более поздних версиях. Однако, несмотря на то, что он имеет относительно широкую поддержку, он все же не является стандартом и не должен использоваться, если у вас нет альтернативы. Вы можете указать этот атрибут как:
1 |
<input type="file" id="file-uploader" webkitdirectory /> |
Это позволит вам выбрать папку (также известную как каталог).
Пользователь должен предоставить подтверждение для загрузки каталога.
Как только пользователь нажимает кнопку «Загрузить», происходит загрузка. Здесь следует отметить один важный момент. Массив FileList будет содержаться информацию обо всех файлах в загруженном каталоге как плоскую структуру. Но ключ в том, что для каждого из объектов File атрибут webkitRelativePath будет иметь путь к каталогу.
Например, давайте рассмотрим каталог main и другие папки и файлы в нем.
Теперь объекты File будут заполнены webkitRelativePath:
Вы можете использовать это для рендеринга папки и файлов в любой структуре пользовательского интерфейса по вашему выбору. Используйте этот CodePen для дальнейшего изучения.
9. Давайте перетащим файд и загрузим
Не поддерживать перетаскивание при загрузке файлов — это старомодно, не так ли? Давайте посмотрим, как этого добиться, выполнив несколько простых шагов.
Сначала создайте зону перетаскивания и, при необходимости, раздел для отображения содержимого загруженного файла. Мы будем использовать изображение в качестве файла для перетаскивания сюда.
1 2 3 4 5 6 7 8 9 10 11 |
<div id="container"> <h1>Drag & Drop an Image</h1> <div id="drop-zone"> DROP HERE </div> <div id="content"> Your image to appear here.. </div> </div> |
Получите dropzone и области содержимого по их соответствующим идентификаторам.
1 2 |
const dropZone = document.getElementById('drop-zone'); const content = document.getElementById('content'); |
Добавьте обработчик событий dragover, чтобы показать эффект от того, что будет скопировано.
1 2 3 4 5 |
dropZone.addEventListener('dragover', event => { event.stopPropagation(); event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; }); |
Затем определите, что мы хотим делать, когда изображение брошено. Для этого нам понадобится прослушиватель событий drop.
1 2 3 4 5 6 7 |
dropZone.addEventListener('drop', event => { // Get the files const files = event.dataTransfer.files; // Now we can do everything possible to show the // file content in an HTML element like, DIV }); |
Попробуйте перетащить файл изображения в примере CodePen ниже и посмотрите, как он работает. Не забудьте также посмотреть код для рендеринга сброшенного изображения. Ссылка CodePen:
10. Управление файлами с помощью objectURL
Существует специальный метод URL.createObjectURL() для создания уникального URL из файла. Вы также можете вызвать его с помощью метода URL.revokeObjectURL().
Методы URL.createObjectURL() и URL.revokeObjectURL() позволяют создавать простые строки URL-адресов, которые можно использовать для ссылки на любые данные, на которые можно ссылаться с помощью объекта файла DOM, включая локальные файлы на компьютере пользователя. Простое использование URL-адреса объекта:
1 |
img.src = URL.createObjectURL(file); |
Используйте этот CodePen для дальнейшего изучения URL-адреса объекта. Подсказка: сравните этот подход с подходом, упомянутым в пункте 5 ранее.
Заключение
Во многих случаях нам может быть достаточно встроенной функции HTML, чтобы разобраться с конкретными вариантами использования. Я обнаружил, что file upload это один из таких вариантов, который по умолчанию предоставляет множество интересных функций.
Автор: Tapas Adhikary
Источник: blog.greenroots.info
Редакция: Команда webformyself.