Главная - Инструкции
Красивая AJAX форма для загрузки файлов. HTML5: загрузка файлов с помощью Drag-and-drop Добавляем функциональность Drag-and-Drop
  • HTML

Благодаря нововведениям HTML5 создавать Drag and Drop интерфейсы стало гораздо проще. К сожалению, эти нововведения еще не обладают обширной поддержкой браузеров, но надеюсь в скором времени это изменится (на данный момент работает в Firefox 4+, Chrome и Opera 11.10).

Разметка Сразу говорю, статья написана больше для новичков, чем для профессионалов. Поэтому некоторые моменты будут описываться очень подробно.

Для начала, нам необходимо создать HTML файл с таким содержанием:

Для загрузки, перетащите файл сюда.

Вся работа у нас будет происходить с контейнером dropZone. Теперь добавим стили для нашего документа (style.css):

Body { font: 12px Arial, sans-serif; } #dropZone { color: #555; font-size: 18px; text-align: center; width: 400px; padding: 50px 0; margin: 50px auto; background: #eee; border: 1px solid #ccc; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } #dropZone.hover { background: #ddd; border-color: #aaa; } #dropZone.error { background: #faa; border-color: #f00; } #dropZone.drop { background: #afa; border-color: #0f0; }

В стилях Вы можете заметить три состояния у элемента dropZone: при наведении, если возникает какая-то ошибка и при успешном выполнении.

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

$(document).ready(function() { var dropZone = $("#dropZone"), maxFileSize = 1000000; // максимальный размер файла - 1 мб. });

Дальше мы должны проверить поддерживает ли браузер Drag and Drop, для этого мы будем использовать FileReader функцию. Если браузер не поддерживает Drag and Drop, то внутри элемента dropZone мы напишем «Не поддерживается браузером!» и добавим класс «error».

If (typeof(window.FileReader) == "undefined") { dropZone.text("Не поддерживается браузером!"); dropZone.addClass("error"); }

Следующее что мы сделаем это будет анимация эффекта перетаскивания файла на dropZone. Отслеживать эти действия мы будет с помощью событий «ondragover» и «ondragleave». Но, так как эти события не могут быть отслежены у jQuery объекта, нам необходимо обращаться не просто к «dropZone», а к «dropZone».

DropZone.ondragover = function() { dropZone.addClass("hover"); return false; }; dropZone.ondragleave = function() { dropZone.removeClass("hover"); return false; };

Теперь нам необходимо написать обработчик события «ondrop» - это событие когда перетянутый файл опустили. В некоторых браузерах при перетягивании файлов в окно браузера они автоматически открываются, что бы такого не произошло нам нужно отменить стандартное поведение браузера. Также нам необходимо убрать класс «hover», и добавить класс «drop».

DropZone.ondrop = function(event) { event.preventDefault(); dropZone.removeClass("hover"); dropZone.addClass("drop"); };

Var file = event.dataTransfer.files; if (file.size > maxFileSize) { dropZone.text("Файл слишком большой!"); dropZone.addClass("error"); return false; }

Теперь нам необходимо написать AJAX запрос отсылающий наш файл в обработчик. Для создания AJAX запроса мы будем использовать объект XMLHttpRequest. Добавим для объекта XMLHttpRequest два обработчика событий: один будет показывать прогресс загрузки файла, а второй результат загрузки. В качестве обработчика укажем файл upload.php.

Var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", uploadProgress, false); xhr.onreadystatechange = stateChange; xhr.open("POST", "/upload.php"); xhr.setRequestHeader("X-FILE-NAME", file.name); xhr.send(file);

Теперь займемся функциями прогресса загрузки и результата загрузки. В функции «uploadProgress» нет ничего сложного, лишь простейшая математика.

Function uploadProgress(event) { var percent = parseInt(event.loaded / event.total * 100); dropZone.text("Загрузка: " + percent + "%"); }

В функции «stateChange» мы должны проверить завершен ли процесс загрузки, и если да, то необходимо проверить не возникла ли какая-либо ошибка. Код успешного запроса «200», если же код отличается от этого, то это означает, что произошла ошибка.

Function stateChange(event) { if (event.target.readyState == 4) { if (event.target.status == 200) { dropZone.text("Загрузка успешно завершена!"); } else { dropZone.text("Произошла ошибка!"); dropZone.addClass("error"); } } }

Написание JavaScript части завершено.

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

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

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

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

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

Загрузку файлов с локального компьютера трогать пока не будем, я планирую опубликовать отдельный пост на эту тему, разберем загрузку с удалённого сервера.

Проблемы начинаются с первого же шага. Даже если вы четко понимаете, где искать URL и хорошо умеете пользоваться инструментами вроде firebug, то всё равно потребуется несколько кликов мышкой чтобы получить нужный адрес. Было бы гораздо удобнее просто перетянуть нужную картинку из одного окна браузера в другое.

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

Обратите внимание! Данный пример работает только в браузере Google Chrome. По-идее, поддержка всех необходимых технологий есть в Firefox и Safari, но с ними я пока не разбирался.

В качестве объектов для "перетягивания" я брал в основном картинки с википедии. Было замечено несколько проблем связанных с не латинскими символами в URL картинок, но чтобы не перегружать пример проверками и преобразованиями я их оставил как есть.


Принцип работы

Стандарт HTML5 предусматривает поддержку "перетягивания" объектов страницы (Drag and Drop ). Кстати, пример простейшей реализации D&D я уже показывал - Drag & Drop с использованием HTML5. И, кроме того, есть довольно много JavaScript библиотек, реализующих поддержку D&D.

Но тут важно понимать, что если необходимо "перетягивать" картинки со сторонних ресурсов, то использовать библиотеки не получится. Т.к. вы не сможете добавить свой JS код на чужую страницу. А для того, чтобы загрузить картинку, нам нужно получить её URL, т.е. браузер должен вместе с перетягиваемым объектом передавать и его параметры (например, атрибут src картинки или весь тег img).

В этом случае мы можем создать на своей странице "приёмник" картинок. Это будет обычный div которому назначен обработчик события drop. Если пользователь "сбросит" картинку над этим div"ом, то будет вызван обработчик и в первом параметре он получит объект, содержащий информацию о перетягиваемой картинке.

Реализация

Начнём со страницы нашего приложения.





Images Upload








На ней размещены два блока: images - здесь будем показывать загруженные изображения и img_target - на этот блок нужно перетягивать картинки.

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

Рассмотрим main.js

$(function() {
$("#img_target")
.bind("dragenter", function(event) {
$(this).addClass("drop_here");
return false;
})
.bind("dragleave", function(event) {
return false;
})
.bind("dragover", function(event) {
return false;
})
.bind("drop", function(event) {
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("upload.php", {"file_url":img_data}, function(res) {
var response = eval("(" + res + ")");
$("#images").append($(""));
});
return true;
});

Здесь мы назначаем обработчики событиям dragenter, dragleave и dragover. Все они должны просто возвращать false и, чтобы как-то проинформировать пользователя о том, что можно "сбрасывать" картинку, в обработчике dragenter устанавливаем CSS класс drop_here для блока-приёмника.

Основная часть работы выполняется в обработчике события drop. При возникновении этого события мы читаем информацию о "сброшенном" объекте и "вырезаем" значение атрибута src, т.е. URL картинки (строки 16-18). Информация передается в объекте event.originalEvent.dataTransfer (строка 17).

Затем формируем обычный AJAX запрос и в качестве параметра передаём ему найденный URL.

Серверный скрипт (upload.php) получит URL изображения на удалённом сервере и загрузит его. А в ответе на AJAX запрос он отправит новый URL загруженной картинки.

В свою очередь, обработчик AJAX-запроса создаст тег img и вставит его в блок images. Таким образом, загруженные картинки будут появляться над полем загрузки.

Рассмотрим upload.php

define("BASE_URL", "http://localhost/tests/images-upload/");

function upload_from_url($file_url) {
$url_segments = explode("/", $file_url);
$file_name = urldecode(end($url_segments));
if (false !== $file_name) {
$file_name_parts = explode(".", $file_name);
if (in_array(strtolower(end($file_name_parts)), array("jpeg","jpg","png","gif"))) {
$destination=fopen("upload/".$file_name,"w");
$source=fopen($file_url,"r");
$maxsize=300*1024;
$length=0;
while (($a=fread($source,1024))&&($length "Не указан URL файла");

if (isset($_POST["file_url"])) {
$new_url = upload_from_url($_POST["file_url"]);
$res = array("file_url" => $new_url);
}

echo json_encode($res);

Принцип работы следующий. Читаем URL картинки и пытаемся её загрузить (строки 29-32).

Если картинка загружена, сохраняем её в папку upload. Получение картинки с удалённого сервера осуществляется с помощью функций fread. Файл читаем блоками по 1кБ (строки 15-18). Такой подход позволяет прервать загрузку файла, если его размер превышает заданный предел (в данном случае 300кБ).

После загрузки файла формируем для него URL и отправляем браузеру в формате JSON.

Как видите, реализовать такой загрузчик несложно. И пользоваться им достаточно удобно. Естественно, основным недостатком является поддержка HTML5 браузерами, точнее её отсутствие

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

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.

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

Решение

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

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

Продолжаем создавать нашу drag and drop загрузку, а сегодня мы напишем наш сервер и начнём писать JavaScript код.

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

  • .htaccess
  • index.html
  • style.css
  • upload.php
  • uploads

С файлами index.html и style.css всё понятно. В файле .htaccess у нас просто прописана кодировка, чтобы не было проблем.

AddDefaultCharset UTF-8

Файл upload.php будет загружать файлы на сервер в папку uploads .

Итак, давайте начнём с php . Для этого откройте файл upload.php и пропишите следующее:

В начале файла мы прописываем заголовок Content-Type , чтобы сообщить браузеру, что он получит json . После создаём пустой массив $uploaded и проверяем, есть ли вообще какие-то файлы. Если да, то перебираем их и загружаем в нашу директорию uploads , а, также, заполняем наш главный массив $uploaded подмассивами, которые будут содержать информацию о файлах. В нашем случае это имя файла и его месторасположения . Наконец, мы преобразовываем наш массив в json и выводим его. Как видите, сервер вовсе несложный.

Теперь перейдём к файлу index.html


Перетащите файлы сюда

(function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = function() {
this.className = "dropzone dragover";
this.innerHTML = "Отпустите мышку";
return false;
};

Dropzone.ondragleave = function() {


return false;
};

Dropzone.ondrop = function(e) {
this.className = "dropzone";
this.innerHTML = "Перетащите файлы сюда";
e.preventDefault();
};
})();

Помните класс .dragover , который мы написали в прошлой статье, и я говорил, что он будет применяться, когда над нашим блоком будет какой-то файл? Вот, собственно, это мы сейчас и сделали. Когда над блоком появляется какой-то файл, срабатывает событие ondragover , где мы просто добавляем наш класс .dragover и меняем текст на "Отпустите мышку" . Когда же мы отводим мышку с файлом от нашего блока, то срабатываем событие ondragleave , где мы возвращаем всё в исходное положение. Когда человек "бросает" файл в наш блок, то срабатывает событие ondrop . Там мы снова всё меняем, как было в начале, иначе у нас "зависнет" класс .dragover и отменяем поведение по-умолчанию. Если мы этого не сделаем, то наш файл просто откроется в браузере, чего нам не нужно.

 


Читайте:



Функции VBA для работы с текстом

Функции VBA для работы с текстом

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

Обратная связь на YouTube: как общаться с подписчиками и увеличить их число

Обратная связь на YouTube: как общаться с подписчиками и увеличить их число

Вы хотите стать известным на YouTube? Вы хотите получить столько подписчиков, сколько возможно? Независимо от Вашей темы, для достижения этой цели,...

Личный кабинет столото Столото как зарегистрироваться не получается

Личный кабинет столото Столото как зарегистрироваться не получается

ДРУГИЕ ВОПРОСЫГЛОССАРИЙ ОБЩИЕ ВОПРОСЫ Как купить билет? Выберите способ покупки билетов на странице « » . Подробная инструкция о покупке билетов...

Пользовательский интерфейс на базе Twitter Bootstrap для начинающих Качаем и устанавливаем bootstrap signed

Пользовательский интерфейс на базе Twitter Bootstrap для начинающих Качаем и устанавливаем bootstrap signed

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

feed-image RSS