Анимация во время множественной загрузки файлов на сервер

Как в js во время множественной загрузки файлов на сервер реализовать анимацию загрузки для каждого загружаемого на данный момент файла?

К примеру, у нас есть кнопка для выбора файлов и 2 элемента для отображения информации:

<html>
<head></head>
<body>
    <label id = "fileLoader" type="button">
        <input id = "fileInput" name = "file[]" type = "file" multiple style = "display: none;">
        Add new file
    </label>
    <li>
        <ul>
            <p>
                <progress id = "progressBar_0" value = "0" max = "100"> </progress>
            </p>    
            <p>
                <div id = "progressLoading_0">0/0</div>
            </p>
        </ul>
        <ul>
            <p>
                <progress id = "progressBar_1" value = "0" max = "100"> </progress>
            </p>    
            <p>
                <div id = "progressLoading_1">0/0</div>
            </p>
        </ul>
    </li>
    <script src = "./testJS.js"></script>
</body>
</html>

Сам скрипт:

window.onload = function() {
    // подвязываем переменную к элементу
    var $input = document.getElementById('fileInput');
    $input.addEventListener('change', function(e) {
        // отменяем дейстие браузера
        e.preventDefault();
        // проверяем массив файлов в файловом инпуте
        if($input.files.length > 0) {
            for(var i = 0; i < $input.files.length; i++) {
                var formData = new FormData(),
                    file = $input.files[i],
                    xhr = new XMLHttpRequest();
                // заполняем объект FormData (данные формы)
                formData.append($input.name, file);
                formData.append("id", 1);
                // обработчик для отправки
                xhr.upload.onprogress = function(e){
                    // здесь уже вопросы. event.loaded и event.total во время одновременной выгрузки 2х файлов могут принадлежать как первому файлу, так и второму
                    document.getElementById('progressBar_'+0).value = 100/event.total*event.loaded;
                    document.getElementById("progressLoading_"+0).innerHTML = event.loaded + ' / ' + event.total;
                }
                // готовим ajax запрос
                xhr.open('POST', 'submit.php');

                xhr.onreadystatechange = function(e) {
                    if(e.target.readyState == 4) {
                        if(e.target.status == 200) {
                            // успешно отправили файл
                            return;
                        }
                        else {
                            // произошла ошибка
                        }
                    }
                };
                xhr.send(formData);                      
            }
        }
    });
}

В данный момент, если выбрать, к примеру, 2 файла для загрузки - то в xhr.upload.onprogress event.loaded и event.total в разные моменты времени показывают значения загрузки обоих файлов одновременно.

Вопрос: как сделать так, чтобы состояние 1го файла отображалось в progressBar_0, а состояние 2го - в progressBar_1?


Ответы (1 шт):

Автор решения: Stepan Kasyanenko

Попробуйте так - заменяем var = i на let = i в инициализации цикла, что даст нам локальную переменную i. Используем i для получения прогресс бара.

window.onload = function() {
    // подвязываем переменную к элементу
    var $input = document.getElementById('fileInput');
    $input.addEventListener('change', function(e) {
        // отменяем дейстие браузера
        e.preventDefault();
        // проверяем массив файлов в файловом инпуте
        if($input.files.length > 0) {
            for(let i = 0; i < $input.files.length; i++) {
                var formData = new FormData(),
                    file = $input.files[i],
                    xhr = new XMLHttpRequest();
                // заполняем объект FormData (данные формы)
                formData.append($input.name, file);
                formData.append("id", 1);
                // обработчик для отправки
                xhr.upload.onprogress = function(e){
                    // здесь уже вопросы. event.loaded и event.total во время одновременной выгрузки 2х файлов могут принадлежать как первому файлу, так и второму
                    document.getElementById('progressBar_'+i).value = 100/event.total*event.loaded;
                    document.getElementById("progressLoading_"+i).innerHTML = event.loaded + ' / ' + event.total;
                }
                // готовим ajax запрос
                xhr.open('POST', 'submit.php');

                xhr.onreadystatechange = function(e) {
                    if(e.target.readyState == 4) {
                        if(e.target.status == 200) {
                            // успешно отправили файл
                            return;
                        }
                        else {
                            // произошла ошибка
                        }
                    }
                };
                xhr.send(formData);                      
            }
        }
    });
}
→ Ссылка