В этом руководстве вы узнаете о событиях прокрутки — Scroll Events в JavaScript и о том, как правильно их обрабатывать.
Когда вы прокручиваете документ или элемент, срабатывают события прокрутки. Вы можете инициировать события прокрутки, например, следующими способами:
- Использование полосы прокрутки вручную
- Использование колесика мыши
- Щелчок по ссылке с идентификатором
- Вызов функций в JavaScript
Чтобы зарегистрировать обработчик событий scroll
, вы вызываете метод addEventListener()
для целевого элемента, например:
targetElement.addEventListener('scroll',(event) => { // handle the scroll event });
или назначаете обработчик события свойству onscroll
целевого элемента:
targetElement.onscroll = (event) => { // handle the scroll event };
Прокрутка документа
Как правило, вы обрабатываете события scroll
на window
всей веб-страницы.
Ниже показано, как присоединить обработчик событий к событию scroll
страницы:
window.addEventListener('scroll',(event) => { console.log('Scrolling...'); });
Или вы можете использовать свойство onscroll
для объекта window
:
window.onscroll = function(event) { // };
Свойство onscroll
объекта window
совпадает со свойством document.body.onscroll
, и вы можете использовать их взаимозаменяемо, например:
document.body.onscroll = null; console.log(window.onscroll); // null
Смещение прокрутки
Объект window
имеет два свойства, связанных с событиями прокрутки: scrollX
и scrollY
.
scrollX
и scrollY
возвращают количество пикселей, на которое в данный момент документ прокручивается по горизонтали и вертикали. scrollX
и scrollY
являются значениями с плавающей запятой двойной точности, поэтому, если вам нужны целые значения, вы можете использовать Math.round()
для их округления.
scrollX
и scrollY
равны 0, если документ вообще не прокручивался.
pageXOffset
и pageYOffset
являются псевдонимами scrollX
и scrollY
.
Прокрутка элемента
Как и в случае с объектом window
, вы можете прикрепить обработчик событий scroll
к любому элементу HTML. Однако для отслеживания смещения прокрутки вы используете scrollTop
и scrollLeft
вместо scrollX
и scrollY
.
Свойство scrollTop
задает или получает количество пикселей, на которое содержимое элемента прокручивается по вертикали. Свойство scrollLeft
получает и устанавливает количество пикселей, на которое содержимое элемента прокручивается от его левого края.
В следующем примере показано, как обрабатывать событие scroll
элемента div
с идентификатором scrollDemo
:
<!DOCTYPE html> <html> <head> <title>JS Scroll Events</title> <style> #scrollDemo { height: 200px; width: 200px; overflow: auto; background-color: #f0db4f } #scrollDemo p { /* show the scrollbar */ height: 300px; width: 300px; } </style> </head> <body> <div id="scrollDemo"> <p>JS Scroll Event Demo</p> </div> <div id="control"> <button id="btnScrollLeft">Scroll Left</button> <button id="btnScrollTop">Scroll Top</button> </div> <script> let control = document.querySelector('#control'); control.addEventListener('click', function(e) { // get the scrollDemo let div = document.getElementById('scrollDemo'); // get the target let target = e.target; // handle each button's click switch(target.id) { case 'btnScrollLeft': div.scrollLeft += 20; break; case 'btnScrollTop': div.scrollTop += 20; break; } }); </script> </body> </html>
Лучшие способы
Многие события scroll
срабатывают, когда вы прокручиваете страницу или элемент. Если вы прикрепите прослушиватель событий к событию scroll
, коду в обработчике событий потребуется время для выполнения.
Это вызовет проблему, известную как рывок прокрутки. Эффект рывка прокрутки вызывает задержку, поэтому страница не кажется привязанной к вашему пальцу.
Регулирование событий
Гораздо лучше сделать обработчик событий scroll
легковесным и выполнять его каждые N миллисекунд с помощью таймера. Поэтому вместо использования следующего кода (и вы никогда не должны его использовать):
window.scroll = () => { // place the scroll handling logic here };
Вы должны использовать следующий код:
let scrolling = false; window.scroll = () => { scrolling = true; }; setInterval(() => { if(scrolling) { scrolling = false; // place the scroll handling logic here } },300);
Как это работает:
- Сначала установите для флага
scrolling
значениеfalse
. Если срабатывает событие, установите флагscrolling
вtrue
внутри обработчика событияscroll
. - Затем выполняйте обработчик событий прокрутки с помощью setInterval() каждые 300 миллисекунд, если события прокрутки сработали.
Этот способ обработки события scroll
называется регулированием события, при котором базовая операция onscroll
каждые 300 миллисекунд. Регулирование замедляет скорость выполнения обработчика событий прокрутки.
Пассивные события
В последнее время современные веб-браузеры поддерживают пассивные события для событий ввода, таких как scroll
, touchstart
, wheel
и т. д. Это позволяет потоку пользовательского интерфейса обрабатывать событие непосредственно перед передачей управления вашему пользовательскому обработчику событий.
В веб-браузерах, которые поддерживают пассивные события, вам необходимо добавить флаг passive
к любому прослушивателю событий, который не вызывает preventDefault()
, например:
document.addEventListener( 'scroll', (event) => { // handle scroll event }, { passive: true } );
Без опции passive
код в обработчике событий всегда будет вызываться до того, как поток пользовательского интерфейса выполнит прокрутку.
Заключение
- Событие
scroll
срабатывает при прокрутке веб-страницы или элемента. - Для страницы
scrollX
иscrollY
возвращают количество пикселей, на которое в данный момент документ прокручивается по горизонтали и вертикали. - Для элемента свойства
scrollTop
иscrollLeft
задают или получают количество пикселей, на которое содержимое элемента прокручивается по вертикали и прокручивается от его левого края. - Используйте метод регулирования событий, чтобы лучше обрабатывать события прокрутки. В современных веб-браузерах вы можете использовать пассивные прослушиватели событий.