От автора: Учебник о том, как воссоздать выскальзывающее боковое меню-колонку, которое можно увидеть на вебсайте GoogleNexus 7.
В этом учебнике мы собираемся создать форму выгрузки файлов AJAX, которая позволит пользователям выгружать файлы со своих браузеров, просто перетащив/отпустив или выбрав их индивидуально. В этих целях мы скомбинируем мощный плагин jQuery File Upload с аккуратным jQuery Knob и представим гладкий интерфейс под управлением CSS3/JS.
HTML
Как обычно, начнем с базового документа HTML5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Mini Ajax File Upload Form</title> <!—веб-шрифты Google --> <link href="//fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700" rel='stylesheet' /> <!—Основной файл CSS --> <link href="assets/css/style.css" rel="stylesheet" /> </head> <body> <form id="upload" method="post" action="upload.php" enctype="multipart/form-data"> <div id="drop"> Drop Here <a>Browse</a> <input type="file" name="upl" multiple /> </div> <ul> <!—Здесь будет показана выгрузка файлов --> </ul> </form> <!—Подключаем JavaScript --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="assets/js/jquery.knob.js"></script> <!— Подключаем jQuery File Upload --> <script src="assets/js/jquery.ui.widget.js"></script> <script src="assets/js/jquery.iframe-transport.js"></script> <script src="assets/js/jquery.fileupload.js"></script> <!—Наш основной файл JS --> <script src="assets/js/script.js"></script> </body> </html> |
В начало документа я включил два шрифта из Google Webfonts, а перед закрытием тэга body вы видите несколько библиотек JavaScript. Это библиотека jQuery, плагин jQuery Knob и зависимости для плагина jQuery File Upload. Основной элемент страницы – форма #upload. Внутри нее находится div #drop (принимающий выгрузки drag/drop) и неупорядоченный список. В этом списке будет содержаться элемент li для каждого из переносимых файлов. Ниже приведена сгенерированная разметка выгрузки файла:
1 2 3 4 5 |
<li class="working"> <input type="text" value="0" data-width="48" data-height="48" data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /> <p>Sunset.jpg <i>145 KB</i></p> <span></span> </li> |
Элемент input в вышеприведенном фрагменте скрыт с помощью CSS. Единственное его предназначение – инициализировать плагин jQuery Knob, который создаст красивый элемент загрузки (круговую шкалу). У input есть несколько атрибутов data-*, модифицирующих ее внешний облик. Позже, слушая прогресс выгрузки файла, мы обновим значение этого input, что вызовет перерисовку шкалы. У диапазона справа есть иконка; это может быть либо отметка-«галочка», либо красный крестик.
Код jQuery
С помощью этой формы можно выгружать файлы двумя способами:
Отпустив их в div #drop (во всех браузерах, кроме IE);
Щелкнув по кнопке «browse». Так симулируется щелчок по скрытому input файла, который выводит окно поиска файлов системы. Обратите внимание, что у input файла есть набор множества параметров, который позволяет выбрать зараз более одного файла (однако файлы все равно будут выгружаться индивидуально!).
Поведением по умолчанию этого плагина является размещение файлов в очередь, но мы сделаем так, чтобы файлы выгружались автоматически после выбора/перетаскивания. Ниже можно посмотреть JS:
assets/js/script.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
$(function(){ var ul = $('#upload ul'); $('#drop a').click(function(){ // Симулируйте щелчок по кнопке ввода файла // для показа диалогового окна браузера файлов $(this).parent().find('input').click(); }); // Инициализируйте плагин jQuery File Upload $('#upload').fileupload({ // Этот элемент примет выгрузку файла drag/drop dropZone: $('#drop'), // Эта функция вызывается, когда файл добавляется в очередь; // либо через кнопку «browse», либо перетащить/отпустить: add: function (e, data) { var tpl = $('<li class="working"><input type="text" value="0" data-width="48" data-height="48"'+ ' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><p></p><span></span></li>'); // Прикрепите имя и размер файла tpl.find('p').text(data.files[0].name) .append('<i>' + formatFileSize(data.files[0].size) + '</i>'); // Добавьте HTML к элементу UL data.context = tpl.appendTo(ul); // Инициализируйте плагин 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); // Обновите скрытый input и запустите изменение // для того, чтобы плагин jQuery knob знал, что нужно обновить круговую шкалу 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 укомплектована собственным дизайном jQuery, управляемым интерфейсом, которым можно сразу же пользоваться. Однако, так как нам нужен полностью пользовательский интерфейс, мы воспользуемся не включающей его базовой версией плагина. Чтобы она заработала, передаем несколько опций/внешних вызовов конфигурации. В вышеприведенном коде это:
dropZone – это свойство содержит селектор jQuery элемента, который будет действовать как объект-приемник. Опускаемые в него файлы будут добавляться в очередь выгрузки.
add – эта функция внешнего вызова вызывается при добавлении файла в очередь. Внутри нее мы создаем разметку HTML, которая будет представлять файл, добавляем ее в UL и запускаем метод data.submit(). Он без промедления вызовет прямую выгрузку добавленного файла.
progress – этот внешний вызов выполняется плагином каждые 100мс (настраивается). Второй аргумент (атрибут data) содержит размер файла и количество переданных байтов. Это позволяет нам подсчитать процент выполнения и впоследствии обновить скрытый элемент input, который в свою очередь обновляет шкалу.
fail – эта внешняя функция выполняется, если с вашим скриптом PHP возникла проблема. Скорее всего, это будет означать, что upload.php отсутствует или выдает какую-то ошибку (для исправления потенциальных проблем воспользуйтесь инспектором своего веб-браузера).
Смотрите полный список доступных опций конфигурации на этой странице. Я включил еще несколько источников информации о плагине в раздел Ресурсы и дополнительная информация в конце этого учебника.
Свойство data.context между вызовами этого метода плагина сохраняется. Таким образом мы узнаем, который пункт LI нужно обновлять при событиях прогресса и сбоя закачки.
Скрипт PHP
jQuery File Upload также укомплектован мощным скриптом PHP для управления выгрузки файлов, который можно разместить на своем сервере, но в этом учебнике мы создадим свой собственный. Выгрузки файлов, посылаемые плагином, практически те же самые, что и при выгрузке обычной формы – получить информацию о выгрузке можно через массив $_FILES:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php // Список разрешенных расширений файла $allowed = array('png', 'jpg', 'gif','zip'); if(isset($_FILES['upl']) && $_FILES['upl']['error'] == 0){ $extension = pathinfo($_FILES['upl']['name'], PATHINFO_EXTENSION); if(!in_array(strtolower($extension), $allowed)){ echo '{"status":"error"}'; exit; } if(move_uploaded_file($_FILES['upl']['tmp_name'], 'uploads/'.$_FILES['upl']['name'])){ echo '{"status":"success"}'; exit; } } echo '{"status":"error"}'; exit; |
Как я уже ранее упоминал, хотя можно выбрать сразу несколько файлов, выгружаются они один за другим. Так их гораздо легче контролировать с помощью нашего скрипта PHP. Сейчас файлы просто перемещаются в папку uploads, но можно расширить ее, добавив в базу данных аутентификацию или создание записей.
Вот и все! Надеюсь, вам пригодится эта форма выгрузки файлов ajax! Если у вас возникнут предложения или вопросы, оставьте их в области комментариев.
Автор: Martin Angelov
Источник: //tutorialzine.com/
Редакция: Команда webformyself.
Комментарии (3)