22 декабря 2015
15 февраля 2010
63
SWFUpload + jQuery: очередная имплементация файлового загрузчика
На тему файловых загрузчиков я уже написал три статьи: раз, два, три. Возможно внешний вид файлового загрузчика - моя личная маниакальная одержимость и мне надо к врачу, или же я просто делюсь своими стремлениями к идеалу красоты загрузчика. Искусство мыть слона в действии.
На этот раз будем будем использовать js-библиотеку SWFUpload и jQuery.
Для начала поясню, кто такой SWFUpload и зачем он может быть нужен.
Итак, SWFUpload - это js-библиотека, обертка для флэш-объекта, который позволяет загружать файлы. Только в отличие от обычного файл-аплода, флэш радует нас возможностью выбирать несколько файлов, получать информацию о процессе загрузки и на клиенте оценивать размер и формат выбранных файлов.
SWFUpload дает полную свободу разработчику в имплементации внешнего вида загрузчика - свобода, которая может быть ограничена разве что знанием HTML+CSS.
Собственно, этой свободой я и решил воспользоваться, когда моя мысль добрела до идеи.
Идея заключается в том, чтобы индикатор загрузки и кнопку выбора файла объединить.
Светлая мысль о том, что индикатор можно впиндюрить в элемент, который уже обладает привычным функционалом, не в мою голову пришла первая. Вот замечательный пример интерфейса Виндуз 7:
Не мешает, всегда видно. Красиво и удобно.
Внешний вид того, что будем делать мы:
Лоутек:
Хайтек:
HTML:
<div id="Buttons">
<span id="UploadPhotos">
<input type="button" id="Progress" /><i id="fAddPhotos"></i><input type="button"
id="AddPhotos" value="Upload Photos" />
</span>
</div> <script type="text/javascript">
window.onload = function() { BindSWFUpload();} </script>
CSS:
#Buttons {
padding: 0;
position: relative;
color: #666666;
width: 200px;
text-align: left;
margin: 200px auto 0;
}
#UploadResult{
padding: 0 10px;
}
input#AddPhotos {
}
#Buttons span {
line-height: 32px;
}
#Buttons input, .niceButton {
border-style: none;
border-color: inherit;
border-width: 0;
background: url('../images/btn.png') no-repeat 0 -32px;
color: #666666;
font-size: 14px;
height: 32px;
width: 115px;
cursor: pointer;
outline: none;
text-decoration: none;
line-height: 32px;
}
#Buttons input:hover, #Buttons input.hover, .niceButton:hover {
background-position: 0 0;
color: #333;
outline: 0 none;
}
#Buttons object {
outline: none;
position: absolute;
}
input#Progress
{
background: url('../images/progress.png') no-repeat 0 0px;
width: 115px;
height: 32px;
position: absolute;
width: 0;
padding: 0;
}
JS:
Метод, инициирующий наш флэш-загрузчик BindSWFUpload. В нем мы задаем настройки загрузчика - количество допустимых файлов, дозволенные форматы, ограничение на размер и объявляем хендлеры для разных этапов процесса загрузки.
var swfuPhotos;
function BindSWFUpload() {
var swfuPhotosSettings = {
file_dialog_complete_handler: photos_fileDialogComplete,
upload_progress_handler: photos_uploadProgress,
upload_success_handler: photos_uploadSuccess,
upload_complete_handler: photos_uploadComplete,
swfupload_loaded_handler: swfuploadLoaded,
file_queue_error_handler: photos_fileQueueError,
file_size_limit: "2 MB",
file_types: "*.jpg;*.png",
file_types_description: "JPG, PNG images",
file_upload_limit: "5",
button_placeholder_id: "fAddPhotos"
}
var defaultSettings = {
flash_url: "files/swf/swfupload.swf",
upload_url: "upload.php",
post_params: {
"ASPSESSID": ASPSESSID
},
button_width: 115,
button_height: 32,
button_image_url: "files/images/white50.png",
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_cursor: SWFUpload.CURSOR.HAND
}
swfuPhotos = new SWFUpload($.extend(swfuPhotosSettings, defaultSettings));
}
Ну а теперь подробнее о самом процессе. Рассмотрим две функции - uploadProgress и uploadSuccess. Первый из них отслеживает состояние загрузки файлов - у него два параметра: файл и объем загруженных байт. Несложной функцией мы преобразуем этот объем байт в часть индикатора загрузки, который, в свою очередь, разбит на n частей, где n - количество загружаемых файлов.
var Count = 0;
var UploadedFiles = 0;
function photos_uploadProgress(file, bytesLoaded) {
try {
var pw = 115;
var w = Math.ceil(pw * (UploadedFiles / Count + (bytesLoaded / (file.size * Count))));
$('#Progress').stop().animate({ width: w });
} catch (ex) {
}
}
function photos_uploadSuccess(file, serverData) {
try {
UploadedFiles++;
} catch (ex) {
}
}
В остальных хэндлерах нету ничего особенного, поэтому сюда их копипастить не буду.
В реальном проекте, безусловно, стоит сделать прелоад картинок, реализовать обработку всех ошибок и прочее. Ну а для демонстрации достаточно и этого.
Понравилась статья? Ретвит!
Предыдущая статья про стилизацию файл-инпутов мне очень помогла в одном из проектов. Даже я со своими дизайнерскими мозгами смог применить описанный метод. А нынче у нас даже с индикацией загрузки. Клево!
Два дурацких вопроса:
— Работает ли оно в
Shiretoko 3.1ИЕ6?— Что происходит, если у пользователя не установлен флеш-плеер?
За час до вашего поста Я закончил интеграция асинхронного загрузчика файлов с помощью "uploadify". Интегрировал Я его в CI-фреймворк.
Мучался Я с ним целый день(((.
Если бы на денек раньше выложили данный пост, то сэкономили мне кучу нервов и времени )))
Все равно спасибо за статью - будет время - обязательно прочитаю )))
1. В IE 6 работает
2. Если у пользователя не установлен флеш, то ничего не происходит. На такой случай надо делать другую имплементацию. Чтобы оставить внешний вид без изменений, я рекомендую Ajax Upload.
Димон, бывает. Зато, может быть, у вас появился интересный опыт. Или просто время зря потратили.
Так или иначе, я вас понимаю. Бывает подготовишь материал для статьи, чтобы на следующий день написать текст, но тут какой-то забугорный красавец постит чуть ли не то же самое, или очень похожее. Повторяться - некрасиво. А время потрачено. Такое, наверное, раз пять было.
Если не будет работать - посмотрите фаербагом что происходит с input id="Progress": его ширина должна увеличиваться от 0 до 115.
Указал 5 изображений немалого размера. После этого несколько секунд была зарузка, но анимации не было. ПОтом показало сообщение , что данные переданы.
Т.е. все так же.
Кстати, а флешка сама процесор жрет при этом нехило. При этом лиса тормозит жутко и не отвечает на запросы юзера.
В других браузерах такая же картина или проблема только с FF?
Ну не скажу, что на линуксе флеш идеален, хотя это адобовский компонент, но другие флешки работают. Скорее всего что-то в самом sfw'е.
На жестком диске
остроумно
теперь файл (upload_url: "upload.php") должен принимать и обрабатывать файлы.
Если возникнут трудности, то на сайте загрузчика есть много рабочих примеров - посмотрите. Здесь я показал только часть, касающуюся оформления.
http://demo.swfupload.org/Documentation/#settingsobject
У меня не срабатывало наведение на кнопку! Долго смотрела стили, а оказалось что я взяла jquery-1.4.1 и сней почему-то эффект наведения не работает, а с jquery-1.3.2 работает!
В чем проблема, как здесь с играл css и jquery?
но возник вопрос!
подскажете, возможно ли на одной странице поставить более чем 1 кнопку для загрузки?
SWFupload позволяет это зделать, однако не могу понять как это сделать после Вашего апгрейда..
в место него $(document).ready(function(){});
и соответственно в коде пронумеровать...
спасибо работает :)
Пример работает замечательно.
Здесь есть что-то неверное?
Спасибо за внимание.
Оказывается был глюк с plugin-container.exe ...
Авторам действительно огромное спасибо за их огромный труд в ликбезе, да и просто предоставлении познавательной инфы.
СПАСИБО!!!
Есть ли шанс не внедряясь в структуру флеша сделать так, что бы в конце загрузки он через fade показал белый экран и воскликнул: "Загружено!" на том же белом фоне? (Текст это не проблема, но вот как моргание сделать?)
да, валидировать надо. Эти лимиты пользователь сможет переопределить если очень захочет.
и сразу несколько вопросов:
1. Как вывести названия загруженных файлов списком и ссылки на них(для скачивания).
2. И как вывести ссылку на удаление уже загруженного файла.
На каком сервере происходит дело?
Подскажите, может ли этот аплоадер загружать не только изображения но и файлы другого типа? (*.rar, *.psd)? И если да, то как это реализовать?
есть где-то в файле swfupload.js всего-то строка которую надо поправить!!
помогите, прав ли я?