Завантаження видимих зображень
Припустимо, у нас є клієнт з низькою швидкістю з’єднання, і ми хочемо заощадити його мобільний трафік.
З цією метою ми вирішуємо не показувати зображення відразу, а замінити їх заповнювачами, наприклад:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
Отже, спочатку всі зображення є placeholder.svg
. Коли сторінка прокручується до місця, де користувач може побачити зображення, ми змінюємо src
на значення data-src
, і таким чином зображення завантажується.
Ось приклад в iframe
:
Прокрутіть, щоб побачити, як зображення завантажуються “на вимогу”.
Вимоги:
- Коли сторінка завантажується, зображення на екрані мають завантажуватися негайно, перед будь-яким прокручуванням.
- Деякі зображення можуть бути звичайними, без
data-src
. Код не повинен їх торкатися. - Після того, як зображення завантажено, воно більше не повинно перезавантажуватися під час прокручування/виходу.
P.S. Якщо ви можете, створіть більш просунуте рішення, яке б “попередньо завантажувало” зображення, які знаходяться на одну сторінку нижче/після поточної позиції.
P.P.S. Потрібно обробляти лише вертикальну прокрутку, горизонтально прокручувати не можна.
Обробник onscroll
повинен перевірити, які зображення є видимими, і показати їх.
Ми також хочемо запускати його під час завантаження сторінки, щоб виявляти видимі зображення відразу та завантажувати їх.
Код повинен виконуватися під час завантаження документа, щоб він мав доступ до його вмісту.
Або розмістіть його внизу <body>
:
// ...вміст сторінки вище...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// видно верхній край елемента?
let topVisible = coords.top > 0 && coords.top < windowHeight;
// видно нижній край елемента?
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
Функція showVisible()
використовує перевірку видимості, реалізовану isVisible()
, для завантаження видимих зображень:
function showVisible() {
for (let img of document.querySelectorAll('img')) {
let realSrc = img.dataset.src;
if (!realSrc) continue;
if (isVisible(img)) {
img.src = realSrc;
img.dataset.src = '';
}
}
}
showVisible();
window.onscroll = showVisible;
P.S. Рішення також має варіант isVisible
, який “попередньо завантажує” зображення, які знаходяться в межах 1 сторінки вище/під поточною прокруткою документа.