Scroll Events в JavaScript: события прокрутки

В этом руководстве вы узнаете о событиях прокрутки — 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 задают или получают количество пикселей, на которое содержимое элемента прокручивается по вертикали и прокручивается от его левого края.
  • Используйте метод регулирования событий, чтобы лучше обрабатывать события прокрутки. В современных веб-браузерах вы можете использовать пассивные прослушиватели событий.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript