SWFUpload + jQuery: очередная имплементация файлового загрузчика

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

}
}

 В остальных хэндлерах нету ничего особенного, поэтому сюда их копипастить не буду.

В реальном проекте, безусловно, стоит сделать прелоад картинок, реализовать обработку всех ошибок и прочее. Ну а для демонстрации достаточно и этого.

Демо Скачать

Понравилась статья? Ретвит!

Расскажите друзьям

Оцените статью:
  • 1
  • 2
  • 3
  • 4
  • 5

Комментарии — 63

Ruby Roid
Спасибо, статья понравилась, уже думаю, где бы это применить.
Саша Кириллов
Жень, спасибо.

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

Два дурацких вопроса:
— Работает ли оно в Shiretoko 3.1 ИЕ6?
— Что происходит, если у пользователя не установлен флеш-плеер?
Димон
Это называется закон заподла в действии (((
За час до вашего поста Я закончил интеграция асинхронного загрузчика файлов с помощью "uploadify". Интегрировал Я его в CI-фреймворк.
Мучался Я с ним целый день(((.
Если бы на денек раньше выложили данный пост, то сэкономили мне кучу нервов и времени )))

Все равно спасибо за статью - будет время - обязательно прочитаю )))

#
Димон
Евгений
Саша, вопросы отнюдь не дурацкие.
1. В IE 6 работает
2. Если у пользователя не установлен флеш, то ничего не происходит. На такой случай надо делать другую имплементацию. Чтобы оставить внешний вид без изменений, я рекомендую Ajax Upload.

Димон, бывает. Зато, может быть, у вас появился интересный опыт. Или просто время зря потратили.
Так или иначе, я вас понимаю. Бывает подготовишь материал для статьи, чтобы на следующий день написать текст, но тут какой-то забугорный красавец постит чуть ли не то же самое, или очень похожее. Повторяться - некрасиво. А время потрачено. Такое, наверное, раз пять было.
Kykyryzo
Здорово, мне понравилось, хоть и я не долюбливаю флеш, но в том, что касается загрузки файлов, лучше ничего пока нет
Albanec
Большое спасибо, Евгений.
Анна из Одессы
Честно говоря, никогда так не делала. Просто не знала о такой возможности. Теперь попробую, спасибо!
Разработчик
Вот это отличное решение аплоада, из тех которые встречал. на jQuery. Без лишнего функционала легко и доступно. )
Skyman
ff 3.5.8 linux - анимация не работает. сразу показывает, что изображение прикреплено.
#
Skyman
Evgenij
Скайман, может он быстро загружается? Попробуйте файл покрупнее и количеством побольше.
Если не будет работать - посмотрите фаербагом что происходит с input id="Progress": его ширина должна увеличиваться от 0 до 115.
Skyman
Evgenij
Указал 5 изображений немалого размера. После этого несколько секунд была зарузка, но анимации не было. ПОтом показало сообщение , что данные переданы.
Т.е. все так же.
#
Skyman
Skyman
А смену инпута не замечено. Лишь вконце спан с айдишником UploadPhotos исчезает (display:none).
Кстати, а флешка сама процесор жрет при этом нехило. При этом лиса тормозит жутко и не отвечает на запросы юзера.
#
Skyman
Евгений
Подозреваю, что флэш для linux неполноценен.
В других браузерах такая же картина или проблема только с FF?
Skyman
Opera 10.10qt - то же самое
Ну не скажу, что на линуксе флеш идеален, хотя это адобовский компонент, но другие флешки работают. Скорее всего что-то в самом sfw'е.
#
Skyman
Влад
А где фыбрать каталог ?
#
Влад
Evgenij
На жестком диске
Влад
Evgenij
На жестком диске


остроумно
#
Влад
Evgenij
Каков вопрос, таков и ответ ;)
Максим
Залил на сервер, пытаюсь загрузить файл, пишет 1 image attached, а самого файла на сервере то нет, что нужно еще сделать?
#
Максим
Евгений
Максиим,
теперь файл (upload_url: "upload.php") должен принимать и обрабатывать файлы.
Если возникнут трудности, то на сайте загрузчика есть много рабочих примеров - посмотрите. Здесь я показал только часть, касающуюся оформления.
Максим
А как насчет имя переменной файла, в которой upload.php обращается к файлу, где ее указывать?
#
Максим
Evgenij
задается параметром file_post_name
http://demo.swfupload.org/Documentation/#settingsobject
ирина
Спасибо за статью.
У меня не срабатывало наведение на кнопку! Долго смотрела стили, а оказалось что я взяла jquery-1.4.1 и сней почему-то эффект наведения не работает, а с jquery-1.3.2 работает!
В чем проблема, как здесь с играл css и jquery?
#
ирина
Evgenij
Да, Ирина, есть такой косяк. Сам замечал, искал ответ, но не нашел.
Ирина
Спасибо за ответ! будет пока без этого эффекта... будет время покопаемся)))
#
Ирина
John
Евгений! Ваше решение шикарно!!
но возник вопрос!
подскажете, возможно ли на одной странице поставить более чем 1 кнопку для загрузки?
SWFupload позволяет это зделать, однако не могу понять как это сделать после Вашего апгрейда..

#
John  
John
сорри, упустил window.onload
в место него $(document).ready(function(){});
и соответственно в коде пронумеровать...

спасибо работает :)
#
John  
Valentin
А пример Ваш у меня только одного не работает или у всех? Пробовал уже пллагин: http://blogs.bigfish.tv/adam/2009/06/14/swfupload-jquery-plugin/ - не работает (оставил там коммент), хотя раньше работал ... Да даже на самом сайте разработчика - http://demo.swfupload.org/v220/eidemo/index.php - не работает ...
#
Valentin
Evgenij
Valentin, очевидно проблема у вас (возможно выключен js или не установлен(выключен) флэш.
Пример работает замечательно.
Valentin
Хм ... JS включен, флеш стоит последний. Проверял в FF, Chrome, Safari. Может я что-то не так делаю???

index.html

ASPSESSID = "ciftuemt43pxrh55jjdohm3o";
window.onload = function() { BindSWFUpload();}


script.js
function BindSWFUpload() {
var swfuPhotosSettings = {
............
file_post_name: 'uploadfile',
............

upload.php
$uploaddir = $_SERVER["DOCUMENT_ROOT"] . '/upload/';
$uploaddir = str_replace('//', '/', $uploaddir);
$file = $uploaddir . basename($_FILES['uploadfile']['name']);
$size = $_FILES['uploadfile']['size'];
if($size > 1048576)
{
echo "error file size > 1 MB";
unlink($_FILES['uploadfile']['tmp_name']);
exit;
}
if(move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file))
{
echo "success";
}
else
{
echo "error ".$_FILES['uploadfile']['error']." --- ".$_FILES['uploadfile']['tmp_name']." %%% ".$file."($size)";
}

Здесь есть что-то неверное?

Спасибо за внимание.
#
Valentin
Valentin
Проверю - отпишусь.
#
Valentin
Владимир
Все как-то ленюсь спасибо авторам за сайт сказать, а между тем, это самое малое, что можно сделать. Большое спасибо за Ваш сайт, ребята! Читал далеко не все статьи у вас, но все что читал действительно качественный материал, а не вода. Заниматься дизайном как-то времени не хватает, да и фантазии (с этим уже смирился :) ) А требования конечно сам себе выдвигаешь строгие, изюминки вечно хочется. Вот у вас мыслями креативными заряжаюсь. Так держать! ))
#
Владимир
Valentin
Проверю - отпишусь.


Оказывается был глюк с plugin-container.exe ...

Авторам действительно огромное спасибо за их огромный труд в ликбезе, да и просто предоставлении познавательной инфы.

СПАСИБО!!!
#
Valentin
PuMi
Неудобно что эта кнопка заточена под надпись "Upload photo", если надпись будет побольше, то текст не будет помещаться в кнопку и и надо увеличивать изображения в фотошопе.
#
PuMi
Данил
Скрипт хороший, хотелось бы еще к нему прикрутить чтоб после загрузки рядом с названием фото была сама маленькая фоточка, которая загрузилась и окошко шде можно было написать текст фотки, как это можно реализовать?
#
Данил
Evgenij
В сам swfupload встроена такаая функциональность. Смотри документацию swfupload
=dAntaeuSb=
Заме4ательные статьи, постоянно захожу на ваш сайт :) Спасибо, прочитал все ваши материалы, особенно понравилось про iPhone, сделал таким образом прокрутку новостей на сайте :) Очень удобно. Но собственно, вопрос:
Есть ли шанс не внедряясь в структуру флеша сделать так, что бы в конце загрузки он через fade показал белый экран и воскликнул: "Загружено!" на том же белом фоне? (Текст это не проблема, но вот как моргание сделать?)
#
=dAntaeuSb=
Александо
Отлично! Спасибо большое! А можно вопрос, возможно глупый, сможет ли в данном способе пользователь обойти file_size_limit,file_types и file_upload_limit? Необходима ли повторная валидация на стороне сервера?
#
Александо
Zhendalf
Александро,
да, валидировать надо. Эти лимиты пользователь сможет переопределить если очень захочет.
Arconas
А есть ли возможность использовать не картинку для кнопки, а обычный input type button? Без placeholderid он просто не хочет работать.
Сергей
Спасибо за статью!
и сразу несколько вопросов:
1. Как вывести названия загруженных файлов списком и ссылки на них(для скачивания).
2. И как вывести ссылку на удаление уже загруженного файла.
Сергей
Еще один вопрос, каким шрифтом ты делал надпись на кнопке?
tester
Народ, подскажите, почему невозможно загружать с помощью этого загрузчика файлы больше 2 МБ. Несмотря на то, что file_size_limit : "100 MB".
#
tester
Zhendalf
Думаю вам стоит посмотреть настройки сервера, потому что с помощью этого загрузчика можно загружать очень большие файлы.
Chips
У меня стоит винда 7, в ней возникла слюдующая проблема: днный загрузчик, как и многие другие в независимости от размера файла, визуально как бы загружают файл за секунду т.е. полоса загрузки пробегает до конца моментально и дальше висит пока файл реально не загрузится. В чем может быть проблема?
#
Chips
Zhendalf
Chips, у меня аналогичная ситуация возникала, когда траффик шел через прокси. Например, я для тестирования использовал Фиддлер. Файл моментально попадал в фиддлер и индикатор загрузки сразу же подходил к концу.
Chips
ну тут дело не в прокси. в ХР работает нормально и локально и на сервере а вот в семерке нехочет
#
Chips
Zhendalf
Я пробовал и на XP (IIS 6) и на семерке (IIS 7).
На каком сервере происходит дело?
Chips
http://jazzkirov.ru/UploadButton/ попробуй
#
Chips
Zhendalf
Попробовал. Работает нормально.
Chips
У тебя семерка стоит?
#
Chips
Chips
Блин у других на семерке работает. Значит проблема чисто у меня!
#
Chips
Chips
Пытался сделать так чтобы информация о загруженом файле записалась в базу данных, но почему-то sql запросы в файлее upload.php неработают. В чем может быть причина?
#
Chips
Альфа
Как вывести в upload.php что-то а не только тупо загрузить файл??
#
Альфа
Alex
Как сделать чтобы после загрузки фоток не появлялось сообщение а переходило автоматом на какую нибудь страницу или обновляло эту?
#
Alex
Дмитрий
Приятный сайт у Вас :)
Подскажите, может ли этот аплоадер загружать не только изображения но и файлы другого типа? (*.rar, *.psd)? И если да, то как это реализовать?
Александр
Добрый день! в ie6 возникла проблема - в хэндлер uploadSuccess почему-то параметр serverData приходим пустым! Кто-нибудь сталкивался с подобным?
#
Александр
Дмитрий
Очень полезная статья. Я посмотрел, скачал пример и на его основе быстро создал пример под свою задачу и потом переписал на своё приложение =) СПС.
#
Дмитрий
john
подскажите как сделать чтоб работало на русскоязычном домене?
#
john
john
скрипт напрочь отказывается работать если домен состоит из: xn--80adxhks.xn--p1ai
есть где-то в файле swfupload.js всего-то строка которую надо поправить!!
помогите, прав ли я?
#
john
Иван
Как можно сделать, что бы после загрузки файлов можно было использовать еще раз загрузчик?
#
Иван
Максим
А вот мне бы хотелось совместить кнопку загрузки с привью загружаемого файла. То есть вначале пустой квадрат для картинки, он же кнопка выбора, после загрузки картинки, можно еще раз по ней кликнуть, для замены картинки. Индикатор загрузки либо убрать совсем, либо отображать его поверх кнопки-картинки, после загрузки -убрать индикатор. Вот как такое сделать?
#
Максим

Новый комментарий

как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть
как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть

metin2 pvp metin2 pvp serverler pvp serverler