Отслеживание процесса загрузки файла

Последнее обновление: 13.11.2023

При загрузке больших файлов через File API может быть полезно информировать пользователей о ходе операции чтения. Для этой цели тип FileReader позволяет обрабатывать событие progress. В обработчик этого события передается объект, который имеет тип ProgressEvent и который предоставляет следующие свойства:

  • lengthComputable: булевое свойство, которое указывает, можно ли вычислить прогресс (количество прочитанных байтов) или нет.

  • loaded: 64-битное целое число без знака, которое указывает на объем уже загруженных данных

  • total: 64-битное целое число без знака, которое хранит общее количество загружаемых данных

Например, возьмем следующую страницу:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    #progress {width:0; height:100%; background-color:#ccc;}
    #progress-bar {width:100px; height:20px; border:1px solid #888;}
    </style>
</head>
<body>
<input type="file" id="files" multiple /><br><br>
<div id="progress-bar">
    <div id="progress"></div>
</div>
<script>
const progressbar = document.getElementById("progress-bar");
const progress = document.getElementById("progress");
// отслеживаем прогресс загрузки
function updateProgress(e) {  
    if (e.lengthComputable) {    
        const percentLoaded = Math.round((e.loaded / e.total) * 100);    
        if (percentLoaded < 100) {      
            progress.style.width = percentLoaded + "%";      
            progress.textContent = percentLoaded + "%";
        } 
    }
}
// обрабатываем выбор файлов
function handleFileSelected(event) { 
    progress.style.width = "0%";  
    progress.textContent = "0%";  

    const reader = new FileReader();
    reader.onprogress = updateProgress;  
    reader.onerror = (e) => console.error(e.target.error);  
    reader.onload = () => {    
        progress.style.width = "100%";    
        progress.textContent = "100%";
    };
    if(event.target.files.length>0) reader.readAsBinaryString(event.target.files[0]);
}
document.getElementById("files").addEventListener("change", handleFileSelected);
</script>
</body>
</html>

На странице определен элемент <input> для выбора файла. Для индикации загрузки файла на странице определен элемент <div id="progress-bar"> с вложенным элементом <div id="percent">.

В качестве обработчика события change для этого элемента <input> используется функция handleFileSelected. В ней устанавливаем начальные значения для индикатора загрузки:

progress.style.width = "0%";  
progress.textContent = "0%"; 

Затем создаем объект FileReader и для его события progress в качестве обработчика применяем функцию updateProgress. В ней рассчитываем текущее состояние загрузки и соответствующим образом обновляем ширину и текст элемента progress.

function updateProgress(e) {  
    if (e.lengthComputable) {    
        const percentLoaded = Math.round((e.loaded / e.total) * 100);    
        if (percentLoaded < 100) {      
            progress.style.width = percentLoaded + "%";      
            progress.textContent = percentLoaded + "%";
        } 
    }
}

Поскольку для элемента progress используется серый фоновый цвет, то увеличение ширины приведет к увеличению закрашенной области, что будет индикатором загрузки. И кроме того, по тексту элемента мы сможем увидеть процент данных загруженного файла.

Когда загрузка завершена, у объекта FileReader срабатывает событие load, в котором устанавливаем финальные значения для элемента progress.

reader.onload = () => {    
    progress.style.width = "100%";    
    progress.textContent = "100%";
};

В конце обработчика выбора файла начинаем его загрузку как набора байтов:

if(event.target.files.length>0) reader.readAsBinaryString(event.target.files[0]);

Для демонстрации обработки прогресса загрузки здесь никак загруженные данные не используются, но естественно мы можем получить эти данные, как описывалось в прошлой статье, и каким-нибудь образом использовать.

Таким образом, при выборе файла начнется загрузка, а элемент progress отобразит индикацию загрузки.

Индикация загрузки файлов с помощью FileReader в JavaScript
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850