Подія progress в JavaScript — хід завантаження даних


Загальний опис

progress — це подія в JavaScript, яка виникає, коли медіа-елемент, наприклад, відео або аудіо, завантажує свої дані. Подія progress дозволяє відстежувати стан завантаження файлу, зокрема, коли нові частини даних були отримані. Це особливо корисно для медіафайлів, які передаються через мережу частинами, а не завантажуються миттєво.

Коли браузер завантажує відео або аудіо, подія progress дозволяє отримати інформацію про те, скільки даних було завантажено. Об'єкт події містить властивості, такі як event.loaded, що показує кількість байтів, які були завантажені, та event.total, що вказує загальний розмір файлу (якщо він відомий). Це дає можливість, наприклад, створити індикатор прогресу завантаження медіафайлу, який візуально показує користувачеві хід процесу.

Приклад використання:

let video = document.getElementById('myVideo');
video.addEventListener('progress', function(event) {
  if (event.lengthComputable) {
    let percentLoaded = (event.loaded / event.total) * 100;
    console.log(`Завантажено: ${percentLoaded}%`);
  }
});

У цьому прикладі ми відслідковуємо, скільки відсотків відео було завантажено, і виводимо це у консоль. Подія progress корисна для ситуацій, коли потрібно показати користувачам завантаження великих медіафайлів, які не можуть бути отримані миттєво.

Якщо браузер не може визначити загальний розмір медіафайлу (наприклад, через особливості мережі або сервера), подія progress все одно спрацьовує, але властивість event.lengthComputable буде false. У такому випадку ви не зможете визначити точний відсоток завантаження, але все одно можете виводити інші повідомлення про хід завантаження.

автор: Bond

Порада

Використовуйте progress для відображення статусу завантаження не тільки для медіафайлів, але й для інших типів великих файлів, наприклад, при завантаженні через API.

автор: Bond
Порада

Подія progress може спрацьовувати багато разів під час завантаження медіа, що дозволяє постійно оновлювати стан завантаження. Однак подія не спрацьовує після завершення завантаження медіа. Для цього є інша подія — canplaythrough, яка сигналізує про те, що медіафайл повністю готовий до безперервного відтворення.

автор: Bond
Порада

Подія progress не показує момент завершення завантаження медіафайлу. Для цього використовуйте canplaythrough або інші події, наприклад, loadeddata.

автор: Bond

Синтаксис

element.addEventListener('progress', function(event) {
  // Ваш код
});

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE
66 57 11.1 53 16
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
66 66 57 11.3
Підтримка: серверні переглядачі
Переглядач Node.js Deno
15.0.0 1.0

Приклади

+ запропонувати свій приклад у пісочниці

HTML

<video id="myVideo" width="320" height="180" controls poster="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180' viewBox='0 0 64 36' preserveAspectRatio='none'%3E%3Crect width='64' height='36' fill='%23264653'/%3E%3Ccircle cx='32' cy='18' r='10' fill='%23e9c46a'/%3E%3Cpath d='M29 12 38 18 29 24Z' fill='%23264653'/%3E%3C/svg%3E">
    Ваш браузер не відтворює відео.
</video>

JS

let video = document.getElementById('myVideo');
let lastUpdate = 0;

video.addEventListener('progress', function() {
  let now = Date.now();
  if (now - lastUpdate > 1000) { // Оновлюємо не частіше разу на секунду
    if (video.buffered.length && video.duration) {
      let percent = (video.buffered.end(video.buffered.length - 1) / video.duration) * 100;
      console.log(`Оновлено не частіше разу на секунду: завантажено ${percent.toFixed(1)}%`);
    }
    lastUpdate = now;
  }
});

video.src = silentWav(30);

// — службове: беззвучний WAV замість медіафайла, збирається просто тут —
function silentWav(seconds = 3, rate = 8000) {
  const size = seconds * rate;  // 8-бітний моно PCM: один байт на семпл
  const le = (value, bytes) => String.fromCharCode(...Array.from({ length: bytes }, (_, i) => value >> 8 * i & 255));
  const head = `RIFF${le(36 + size, 4)}WAVEfmt ${le(16, 4)}${le(1, 2)}${le(1, 2)}${le(rate, 4)}${le(rate, 4)}${le(1, 2)}${le(8, 2)}data${le(size, 4)}`;

  return `data:audio/wav;base64,${btoa(head + '\u0080'.repeat(size))}`;
}
автор: Bond

HTML

<video id="myVideo" width="320" height="180" controls poster="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180' viewBox='0 0 64 36' preserveAspectRatio='none'%3E%3Crect width='64' height='36' fill='%23264653'/%3E%3Ccircle cx='32' cy='18' r='10' fill='%23e9c46a'/%3E%3Cpath d='M29 12 38 18 29 24Z' fill='%23264653'/%3E%3C/svg%3E">
    Ваш браузер не відтворює відео.
</video>
<progress id="progressBar" max="100" value="0"></progress>

JS

let video = document.getElementById('myVideo');
let progressBar = document.getElementById('progressBar');

video.addEventListener('progress', function() {
  // У медіаелемента progress — звичайна подія без полів про обсяг:
  // скільки завантажено, каже сам елемент через buffered
  if (video.buffered.length && video.duration) {
    let percent = (video.buffered.end(video.buffered.length - 1) / video.duration) * 100;
    progressBar.value = percent;
    console.log(`Завантажено ${percent.toFixed(1)}%`);
  } else {
    console.log('Поки нічого не завантажено');
  }
});

video.src = silentWav(30);

// — службове: беззвучний WAV замість медіафайла, збирається просто тут —
function silentWav(seconds = 3, rate = 8000) {
  const size = seconds * rate;  // 8-бітний моно PCM: один байт на семпл
  const le = (value, bytes) => String.fromCharCode(...Array.from({ length: bytes }, (_, i) => value >> 8 * i & 255));
  const head = `RIFF${le(36 + size, 4)}WAVEfmt ${le(16, 4)}${le(1, 2)}${le(1, 2)}${le(rate, 4)}${le(rate, 4)}${le(1, 2)}${le(8, 2)}data${le(size, 4)}`;

  return `data:audio/wav;base64,${btoa(head + '\u0080'.repeat(size))}`;
}
автор: Bond

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле веде сходинками (розділ → тип → сторінка), а хибний ключ підкреслить хвилею.
[[!sandbox/S0oh1hBm]] Живий приклад окремим рядком — саме вікно результату. Той самий ключ зі знаком !: наберіть [[! і дійдіть сходинками до потрібної сторінки, список покаже її приклади.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Правка
Зворотний зв'язок
Вхід