Для начала, конечно, понадобиться создать элемент, который будет «ловить» файл. Кроме того, поместим в этот элемент span-тег для вывода сообщений о состоянии загрузки и input с типом file , чтобы не ограничивать выбор файла лишь перетаскиванием, а так же дать возможность пользователям выбрать файл нажатием на эту обозначенную область. Конечный вид такой структуры представлен ниже.

Нажмите сюда или перетащите файл для загрузки.

CSS к данному HTML коду ничем не примечателен, за исключением оформления поля input :

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

Так же описываем два класса, которые при добавлении к области «захвата» файла будут сигнализировать об успешной загрузке файла или же об ошибке, при возникновении таковой:

#drop-zone.success{ background-color:#2ecc71; } #drop-zone.error{ background-color:#e74c3c; }

Теперь можем перейти к написанию «экшена» нашей страницы. Для начала запишем в переменные ссылки на объекты, к которым будем достаточно часто обращаться:

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

После этого избавимся от событий по умолчанию при попадании курсора в нашу область приема файла следующим образом:

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);

В обоих случаях событие завершается вызовом функции sendFile , в которую передается полученный от пользователя файл.

Эта функция отвечает за передачу файла серверу. Ее описание можете увидеть ниже.

Var sendFile = function(file) { // удаляем классы состояния, которые могли быть добавлены // если пользователь уже пытался что либо загрузить dropZone.classList.remove("success"); dropZone.classList.remove("error"); // делаем проверку при помощи регулярного выражения на тип файла // (в примере только изображения допускаем к загрузке) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/i; if (!re.exec(file.name)) { msgConteiner.innerHTML = "Недопустимый формат файла!"; dropZone.classList.remove("success"); dropZone.classList.add("error"); } else { var fd = new FormData(); // создание объекта формы fd.append("upfile", file); // добавление файла в форму отправки var xhr = new XMLHttpRequest(); xhr.open("POST", "./upload.php", true); xhr.upload.onprogress = showProgress; xhr.onreadystatechange = statChange; xhr.send(fd); // отправка на сервер } }

Как Вы могли заметить, перед отправкой данных на сервер еще задаются два события, из которых первое отвечает за отображения прогресса загрузки, а второе за оповещение о результате загрузки. Действуют они следующим образом:

Var showProgress = function(e) { if (e.lengthComputable) { // расчет процента загрузки var percent = Math.floor((e.loaded / e.total) * 100); // вывод текущего процента msgConteiner.innerHTML = "Загрузка... ("+ percent +"%)"; } }; var statChange = function (e) { if (e.target.readyState == 4) { // по завершению обработки запроса к серверу if (e.target.status == 200) { // если запрос выполнен успешно msgConteiner.innerHTML = "Загрузка успешно завершена!"; dropZone.classList.remove("error"); dropZone.classList.add("success"); document.getElementById("showUpFile").innerHTML = this.responseText; } else { // иначе msgConteiner.innerHTML = "Произошла ошибка!"; dropZone.classList.remove("success"); dropZone.classList.add("error"); } } }

Завершающим этапом будет обработка получаемых сервером данных.

Предоставить возможность пользователю загружать файлы на сервер перетаскивая их например, с рабочего стола. Причем чтобы была возможность перетащить сразу несколько файлов.

Решение

Как видно из примера выше, файлы отправляются на сервер сразу же после выбора. Отправим их по событию:

Window.onload = function(){ var uploader = new qq.FileUploader({ autoUpload: false, element: document.getElementById("file-uploader"), action: "php/upload.php" }); $("#startUpload").on("click", function(){ uploader.uploadStoredFiles(); }); };

Результат

В целом у плагина много опций и настроек, имеются колбеки. Все это описано . Fineuploader находится в постоянной разработке, поэтому рекомендую при привязке посещать репозиторий и брать свежую версию.

Стилизация

Плагин создает свою структуру на базе класса.qq-uploader, все элементы описаны в css файле fileuploader.css

На заметку

Если ослы упорно отказываются работать, открываем скрипт, ищем там строку:

Var form = qq.toElement("");

и меняем на:

Var form = qq.toElement("");

В этом уроке мы сделаем небольшую AJAX форму для загрузки файлов, которая позволит посетителям загружать файлы с помощью или при помощи обычного выбора файлов.

Мы будем использовать плагины jQuery File Upload и jQuery Knob для отображения .

Т.к. форма будет иметь возможность загружать файлы двумя способами, она будет работать даже если drag/drop не поддерживается.

HTML

Как обычно, начнем с HTML5 разметки:

Mini Ajax File Upload Form Drop Here Browse

В теге нашего документа, подключаем шрифты Google Webfonts, а перед закрытием тега — JavaScript библиотеки: jQuery, jQuery Knob и jQuery File Upload.

Главный элемент страницы — форма #upload . Внутри нее элемент #drop (принимает файлы с использованием drag&drop) и список, в котором будут отображаться загружаемые файлы. Разметка, которая будет генерироваться для загруженных файлов:

  • Sunset.jpg 145 KB

  • Элемент input будет спрятан с помощью CSS. Он нужен для инициализации плагина jQuery Knob, который будет рисовать файла. Input имеет атрибуты data-* , которые используются для обновления шкалы. Позже, когда мы будет отслеживать прогресс загрузки, мы будем обновлять эти значения для перерисовки шкалы. span будет содержать зеленую галку или красный крест.

    jQuery

    У посетителя будет 2 способа загрузки файла:

    • Перетащить файл в окно браузера (в IE не работает).
    • Нажатием на кнопку browse. Будет имитировано нажатие на спрятанный input и показано системное окно выбора файлов. Обратите внимание, что input имеет параметр multiple параметр, что позволит выбирать много файлов за один раз.

    Когда файлы будут выбраны, они помещаются в очередь для последующей автоматической загрузки:

    $(function(){ var ul = $("#upload ul"); $("#drop a").click(function(){ // имитация нажатия на поле выбора файла $(this).parent().find("input").click(); }); // инициализация плагина jQuery File Upload $("#upload").fileupload({ // этот элемент будет принимать перетаскиваемые на него файлы dropZone: $("#drop"), // Функция будет вызвана при помещении файла в очередь add: function (e, data) { var tpl = $("

  • "); // вывод имени и размера файла tpl.find("p").text(data.files.name) .append("" + formatFileSize(data.files.size) + ""); data.context = tpl.appendTo(ul); // инициализация плагина jQuery Knob tpl.find("input").knob(); // отслеживание нажатия на иконку отмены tpl.find("span").click(function(){ if(tpl.hasClass("working")){ jqXHR.abort(); } tpl.fadeOut(function(){ tpl.remove(); }); }); // Автоматически загружаем файл при добавлении в очередь var jqXHR = data.submit(); }, progress: function(e, data){ // Вычисление процента загрузки var progress = parseInt(data.loaded / data.total * 100, 10); // обновляем шкалу data.context.find("input").val(progress).change(); if(progress == 100){ data.context.removeClass("working"); } }, fail:function(e, data){ // что-то пошло не так data.context.addClass("error"); } }); $(document).on("drop dragover", function (e) { e.preventDefault(); }); // вспомогательная функция, которая форматирует размер файла function 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) + " KB"; } });

    В jQuery File Upload есть собственный интерфейс, но мы используем базовую версию плагина для создания собственного дизайна интерфейса. И чтобы наш интерфейс работал, мы передаем плагину несколько параметров / колбэков:

    • dropZone – этот параметр содержит jQuery селектор, который будет принимать перетаскиваемые файлы. Файлы, брошенные на него, будут добавлены в очередь загрузки.
    • add – функция вызывается при добавлении файла в очередь загрузки. Она будет генерировать разметку для файлов и вызвать метод data.submit() .
    • progress – Эта функция будет вызываться каждые 100ms (можно изменить). Второй аргумент содержит размер файла и количество загруженных байт. Это позволяет отслеживать прогресс и обновлять шкалу.
    • fail – функция вызывается при возникновении ошибки.
    PHP

    В комплект jQuery File Upload входит также и PHP скрипт для обработки файлов на сервере, но мы напишем свой. Процесс загрузки фалов будет происходить также как и при обычной загрузке, поэтому всю информацию о них мы можем получить из глобального массива $_FILES:

    На этом всё, надеюсь статья была полезной для Вас.

    Скачать исходные файлы вы можете

    This markup doesn"t have anything specifically to do with drag and drop. It"s just a normal, functional , albeit with some extra HTML elements for potential states.

    Choose a file or drag it here. Upload Done! Error! .

    We"ll hide those states until we need them:

    Box__dragndrop, .box__uploading, .box__success, .box__error { display: none; }

    A little explanation:

    • Regarding states: .box__uploading element will be visible during the Ajax process of file upload (and the others will still be hidden). Then .box__success or .box__error will be shown depending on what happens.
    • input and label are the functional parts of the form. I wrote about styling these together in my post about customizing file inputs . In that post I also described the purpose of attribute. The input and label also serve as an alternative for selecting files in the standard way (or the only way if drag and drop isn"t supported).
    • .box__dragndrop will be shown if a browser supports drag and drop file upload functionality.
    Feature detection

    We can"t 100% rely on browsers supporting drag and drop. We should provide a fallback solution. And so: feature detection . Drag & drop file upload relies on a number of different JavaScript API"s, so we"ll need to check on all of them.




    Close