HTML5 Drag-n-Drop загрузка файлов
Задача
Предоставить возможность пользователю загружать файлы на сервер перетаскивая их например, с рабочего стола. Причем чтобы была возможность перетащить сразу несколько файлов.
Решение
Смотрим демо пример. Пример можно забрать архивом. Проверено:
- IE 6-9
- Firefox 3.6-4
- Opera 11.1
- Chrome
- Safari 5
Обращу внимание, что в данном случае проверено != работает:
- IE включая 9-ю версию не поддерживает File API (старая реализация);
- Firefox 3.6+ поддерживает все, что нужно. Для более старых версий — старая реализация;
- Opera 11.1 поддерживает File API, но не поддерживает DnD;
- Chrome, начиная с 10-й версии, поддерживает все, что нужно;
- Safari поддерживает все что нужно с 6-й версии.
Какой толк от этого в таком случае? Пользователи нормальных браузеров получают более удобные сайты.
Что качать:
- библиотеку jquery
- плагинчик (12Kb в несжатом виде)
Быстрый старт
Подключаем скрипты, а в форму добавляет input type=file с id. Если браузер не поддерживает необходимый набор API, пользователь сможет загрузить фото «по старинке». Чтобы у него была возможность добавить несколько фото, динамически добавим кнопку «+», которая будет добавлять поля input type=file. Для этих целей в id поля присутствует 0, чтобы проще было организовать правильные имена добавленных полей.
<script src="path-to/jquery.min.js"></script> <script src="path-tp/jquery.client.js" charset="utf-8"></script> ... <input type="file" id="fileUpload0" multiple="true" size="60">
Для браузеров, которые поддерживают Dnd и File API можно поля type=file вообще скрыть или удалить.
Как это работает
Если не вдаваться особо в детали, тогда принцип работы можно отобразить в виде подобной схемы:

- (DnD API) все начинается когда пользователь отпускает зажатую кнопку мыши — срабатывает событие drop;
- (DnD API) получаем объект DataTransfer от события drop;
- (File API) вызывая DataTransfer.files получаем FileList — список файлов, которые пользователь перетащил в область загрузки;
- (File API) перебирая все файлы читаем их содержимое с помощью объекта FileReader;
- (File API) вызывая FileReader.readAsDataURL(file) каждый раз, когда очередной файл удачно прочитан, формируем data URL объект. Когда он полностью будет сформирован произойдет событие onloadend объекта FileReader;
- когда мы получили объект data:URL, мы можем подставить эти данные в src и отобразить изображение, а так же отправить данные в двоичном виде на сервер;
- (XMLHttpRequest 2) асинхронно отправляем данные, а с помощью новых фишек второй версии протокола XMLHttpRequest получаем данные о состоянии загрузки (событие progress), что позволяет информировать пользователя.
Материалы
- HTML5 File API: множественная загрузка файлов на сервер
- HTML5 Drag and Drop Upload and File API Tutorial
