Мучает вопрос, как грамотно реализовать множественную загрузку файлов, чтобы при загрузке у каждого файла был свой progress bar.
Делал по примеру из статьи https://habr.com/post/109079
Изначально в инпут выбираем нужные файлы, затем при нажатии кнопки "загрузить", js прогоняет объект FileList на наличие выбранных в инпуте файлов и для каждого из них делает ajax запрос с отображением состояния файла, а на выходе сервер (испольую PHP) обрабатывает каждый файл по одному. Насколько эта реализация оправдана и есть ли другие способы реализовать подобное? (без использования сторонних плагинов).
$(document).ready(function(){
$('#file-input').on('change', function(){
var files = $(this).prop('files');
$('#file-container').empty();
for(var file of files)
{
//создаем превью из названия файла и програсс бара
var elem = $('<div class="file-previev"><p>'+file.name+'</p><progress class="file-progress" value="0" max="100"></progress></div>').appendTo($('#file-container'));
//добавляем к контейнеру с превью свойство файла для передачи
elem.get(0).fileInfo = file;
}
});
$('#start').on('click', function(e){
e.preventDefault();
$('#file-container').find('.file-preview').each(function(){
var file = this.file;
var progress = $(this).find('.file-progress');
$.ajax({
url: '/',
type: 'post',
contentType: false,
processData: false,
data: file,
xhr: function(){
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function(evt){
var percent = Math.ceil(evt.loaded/evt.total);
$(progress).attr('value', percent);
}
},
});
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form-upload" method="post">
<input id="file-input" type="file" multiple="true"/>
<button id="start" type="submit">Загрузить</button>
</form>
<div id="file-container"></div>
Дошел до истины, как можно грамотно сделать мультизагрузку с прогресс баром:
$(document).ready(function() {
var input = $('#file-input');
var button = $('#file-submit');
var container = $('#file-container');
input.on('change', function() {
var files = $(this).prop('files');
for (var file of files) {
var elem = $('<div class="file-info"><p>' + file.name + '</p><progress class="progress-bar" max="100" value="0"></progress></div>').appendTo(container);
//добавляем инфу о файле в свойство превью
elem.get(0).file = file;
}
});
//асинхронный колбек закачки файлов
button.on('click', async function(evt) {
evt.preventDefault();
//пускаем закачку каждого файла параллельно с помощью Promise.all и дожидаемся закачки всех файлов с помощью await.
await Promise.all($('.file-info').map(upload));
console.log('готово');
});
//асинхронная функция закачки файла
async function upload(index, elem) {
var data = new FormData();
data.append('file', elem.file);
var progress = $(elem).find('.progress-bar');
//ждем ответа об успешной обработке файла на стороне сервера
const res = await $.ajax({
url: '/',
contentType: false,
processData: false,
data: data,
type: 'post',
xhr: function() {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(evt) {
var percent = Math.ceil(evt.loaded / evt.total * 100);
progress.attr('value', percent);
}
return xhr;
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="file-form" method="post">
<input id="file-input" type="file" multiple>
<button id="file-submit" type="button">Отправить</button><br/>
<div id="file-container"></div>
</form>
Примерно так я сделал решение с мультизагрузкой для себя. Разумеется этот код не идеален и его можно доработать проверками на тип, размер, отмену закачки и т.д.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Задача в том, чтобы на всех страницах-слайдах разместить таймер времени и начиная с первой страницы включить этот таймер
В теле документа есть специальные теги в виде {name}, все бы хорошо, но есть конфликт, когда есть похожий тег {{name}}, где вместо одной фигурной скобки...