Подія scroll у JavaScript — прокручування сторінки


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

scroll – це подія JavaScript, яка викликається при кожній зміні положення прокрутки на сторінці або в межах окремого елемента з можливістю прокрутки. Найчастіше подію scroll використовують для динамічного відображення інформації в залежності від положення сторінки або контейнера, наприклад, для створення ефектів паралаксу, завантаження контенту при скролінгу, приховування або відображення меню тощо. Подію scroll можна відслідковувати як для всього вікна (window), так і для певних елементів, якщо вони мають overflow: scroll або overflow: auto.

Щоб відстежити прокрутку сторінки, додають слухач події scroll до об'єкта window:

window.addEventListener("scroll", () => {
 console.log("Прокрутка вікна:", window.scrollY);
});

Метод scrollY повертає кількість пікселів, на яку сторінка прокручена зверху, тоді як scrollX – зліва. За аналогією, відстеження прокрутки для елемента можна налаштувати додаванням слухача події до цього елемента:

const scrollableDiv = document.getElementById("scrollable");
scrollableDiv.addEventListener("scroll", () => {
 console.log("Прокрутка елемента:", scrollableDiv.scrollTop);
});

Тут scrollTop визначає вертикальну прокрутку для елемента, тоді як scrollLeft відстежує горизонтальну прокрутку.

Оптимізація події scroll:
Оскільки подія scroll викликається дуже часто (під час кожного зміщення прокрутки), важливо оптимізувати її використання, щоб не уповільнювати роботу сторінки. Одним із підходів є застосування функції debounce або throttle, які обмежують кількість викликів функції за часом. Наприклад, бібліотека lodash надає зручний метод throttle:

window.addEventListener("scroll", _.throttle(() => {
 console.log("Оптимізована прокрутка:", window.scrollY);
}, 200));

Така оптимізація допомагає уникнути перевантаження браузера зайвими обчисленнями.

Особливості роботи з мобільними пристроями:
На мобільних пристроях подія scroll також працює, але її обробка може бути менш ефективною через апаратні обмеження. Рекомендується додатково обмежувати виконання важких обчислень для події scroll, щоб зменшити навантаження на мобільні пристрої та уникнути затримок при скролінгу.

автор: Bond

Порада

Для плавного скролінгу використовуйте властивість scroll-behavior: smooth у CSS або JavaScript метод scrollTo з параметром { behavior: "smooth" }, що корисно для довгих сторінок.

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

Створюйте умови для події scroll, наприклад, щоб запускати анімацію тільки при досягненні певної частини сторінки. Це зменшує кількість непотрібних оновлень.

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

Використовуйте requestAnimationFrame, щоб оновлювати інтерфейс тільки в момент, коли браузер готовий до цього, покращуючи плавність прокрутки:

window.addEventListener("scroll", () => {
 requestAnimationFrame(() => {
   console.log("Плавне оновлення під час прокрутки");
 });
});
автор: Bond

Синтаксис

window.addEventListener("scroll", 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

Приклади

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

Цей приклад змінює стиль навігації при скролі більше ніж на 100 пікселів, що робить її більш компактною при прокрутці.

window.addEventListener("scroll", () => {
 const nav = document.querySelector("nav");
 if (window.scrollY > 100) {
   nav.classList.add("scrolled");
 } else {
   nav.classList.remove("scrolled");
 }
});
автор: Bond

Цей код реалізує ледаче завантаження зображень: зображення завантажуються тільки тоді, коли наближаються до видимої області.

HTML

<div class="lazy">перший елемент lazy</div>
<div class="lazy">другий елемент lazy</div>

JS

window.addEventListener("scroll", () => {
 const lazyElements = document.querySelectorAll(".lazy");
 lazyElements.forEach((element) => {
   if (element.getBoundingClientRect().top < window.innerHeight) {
     element.src = element.dataset.src;
   }
 });
});
автор: Bond

Цей приклад дозволяє користувачеві увімкнути або вимкнути ефект прокрутки через кнопку. Текстові блоки плавно з’являються в полі зору при прокручуванні сторінки. Якщо кнопкою вимкнути ефект, анімація припиняється.

HTML

<header>
  <h2 class="title">Event.scroll</h2>
  <p class="description">Анімує текстові блоки, коли вони з'являються в області видимості під час прокрутки.</p>
</header>
<main>
  <div class="result">
    <button id="toggleScrollEffect">Увімкнути/вимкнути ефект скролу</button>
    <!-- Створення кількох текстових блоків для демонстрації ефекту прокрутки -->
    <div class="scroll-section">Секція 1 - Прокрутіть униз</div>
    <div class="scroll-section">Секція 2 - Ефект прокрутки</div>
    <div class="scroll-section">Секція 3 - Анімація при скролі</div>
    <div class="scroll-section">Секція 4 - Прокрутіть далі</div>
    <div class="scroll-section">Секція 5 - Кінець прикладу</div>
  </div>
</main>

CSS

body {
  font-size: 16px;
  line-height: 1.5;
  font-family: monospace;
}

header {
  background-color: #f1f1f1;
  margin-bottom: 25px;
  padding: 15px;
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
}

header h2.title {
  padding-bottom: 15px;
  border-bottom: 1px solid #999;
}

header p.description {
  font-style: italic;
  color: #222;
}

.result {
  background-color: #f8f8f8;
  padding: 15px;
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  text-align: center;
}

button {
  margin-bottom: 20px;
  padding: 10px;
  font-size: 16px;
  cursor: pointer;
}

.scroll-section {
  opacity: 0;
  transform: translateY(50px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
  padding: 20px;
  margin: 50px 0;
  background: #d1e0e0;
}

.scroll-section.visible {
  opacity: 1;
  transform: translateY(0);
}

JS

// Елементи, на які впливає ефект скролу
const sections = document.querySelectorAll(".scroll-section");
const toggleButton = document.getElementById("toggleScrollEffect");
let scrollEffectEnabled = true;

// Функція для перевірки видимості елементів під час скролу
function handleScroll() {
  sections.forEach(section => {
    const sectionTop = section.getBoundingClientRect().top;
    if (sectionTop < window.innerHeight - 50 && scrollEffectEnabled) {
      section.classList.add("visible");
    } else {
      section.classList.remove("visible");
    }
  });
}

// Додаємо слухача події прокрутки
window.addEventListener("scroll", handleScroll);

// Вимкнення та ввімкнення ефекту прокрутки за допомогою кнопки
toggleButton.addEventListener("click", () => {
  scrollEffectEnabled = !scrollEffectEnabled;
  toggleButton.textContent = scrollEffectEnabled ?
  "Вимкнути ефект скролу" :
  "Увімкнути ефект скролу";
});
//# sourceURL=pen.js
автор: 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`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

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

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