scroll и wheel — JavaScript — Дока
Кратко
Секция статьи «Кратко»scroll
— это событие на HTML-элементе. Событие происходит, когда страница или элемент не входит на экран и пользователь её прокручивает. Способ прокрутки может быть любым — колесом мыши, кнопками клавиатуры, с помощью полосы прокрутки на экране.
Событие wheel
происходит, когда пользователь прокручивает колесо мыши. При этом реального прокручивания может не происходить. Например, наша страница полностью помещается на экран, но пользователь пытается её прокрутить. В этом случае событие wheel
будет происходить, а событие scroll
— нет.
Событие wheel
говорит о том, что пользователь пытается прокрутить страницу или элемент, а событие scroll
говорит о том, что прокрутка реально происходит.
Как пишется
Секция статьи «Как пишется»Стандартно с помощью addEventListener
:
document.addEventListener('scroll', function(event) { console.log(event)})
document.addEventListener('scroll', function(event) { console.log(event) })
Отловим все случаи, когда пользователь крутит колесо мыши при наведённом на первый <div>
курсоре:
const div = document.getElementsByTagName('div')[0]div.addEventListener('wheel', function(event) { console.log(event)})
const div = document.getElementsByTagName('div')[0]
div.addEventListener('wheel', function(event) {
console.log(event)
})
Как понять
Секция статьи «Как понять»Разницу между событиями можно понять на демо ниже. wheel
происходит всегда когда пользователь крутит колесо мыши (или что-то его заменяющее), а scroll
только при прокрутке:
Объект события
scroll
Секция статьи «Объект события scroll»scroll
использует базовый элемент события, в котором отсутствует информация о скорости прокрутки и направлении.
Чтобы понять, насколько прокрутилась страница или элемент, этот элемент получают из DOM-дерева или ключевого слова this
и запрашивают свойства scrollTop
или scrollLeft
.
document.addEventListener('scroll', function() { // получаем высоту элемента, на котором произошло событие console.log(this.scrollTop)})
document.addEventListener('scroll', function() {
// получаем высоту элемента, на котором произошло событие
console.log(this.scrollTop)
})
Объект события
wheel
Секция статьи «Объект события wheel»Так как прокрутки при wheel
не происходит, объект события содержит информацию о направлении и «силе» прокрутки в свойствах:
deltaX
— горизонтальная прокрутка. Значение — целое число:- отрицательное, если пользователь прокручивает влево;
0
— если в этом направлении прокрутка не происходит- положительное при прокрутке вправо;
deltaY
— вертикальная прокрутка.Значение — целое число:
- отрицательное, если пользователь прокручивает вверх;
0
— если в этом направлении прокрутка не происходит- положительное при прокрутке вниз;
Если элемент имеет полосу прокрутки, то обычно после события
wheel
происходит scroll
(смотри пример выше). Этого можно избежать, вызвав метод события preventDefault()
.document.addEventListener('wheel', function(event) { // останавливаем поведение по умолчанию, то есть прокрутку event.preventDefault()})
document.addEventListener('wheel', function(event) {
// останавливаем поведение по умолчанию, то есть прокрутку
event.preventDefault()
})
С помощью объекта события можно, например, перемещать элемент по экрану при прокрутке колеса мыши на десктопе. Чтобы посмотреть, как это работает, откройте демо в новой вкладке по ссылке внизу.
На практике
Секция статьи «На практике»Николай Лопин
Секция статьи «Николай Лопин»🛠 Если вы подписались на scroll
, то приготовьтесь получать большое количество событий. Событие будет приходить примерно на каждый кадр. Поэтому в обработчике не рекомендуется производить тяжёлых вычислений и модификации DOM. Это приведёт к потере кадров при отрисовке и ощущения, что сайт тормозит.
🛠 Избежать большого количества событий scroll
можно, используя технику под названием throttling. Её смысл состоит в том, чтобы принимать следующее событие только после истечения некоторого промежутка времени.
const throttle = (func, limit) => { let lastFunc let lastRan return function() { const context = this const args = arguments if (!lastRan) { func.apply(context, args) lastRan = Date.now() } else { clearTimeout(lastFunc) lastFunc = setTimeout(function() { if ((Date.now() - lastRan) >= limit) { func.apply(context, args) lastRan = Date.now() } }, limit - (Date.now() - lastRan)) } }}// код будет срабатывать раз в 1 секундуdocument.addEventListener('scroll', throttle(function() { return console.log('Hey! It is', new Date().toUTCString())}, 1000))
const throttle = (func, limit) => { let lastFunc let lastRan return function() { const context = this const args = arguments if (!lastRan) { func.apply(context, args) lastRan = Date.now() } else { clearTimeout(lastFunc) lastFunc = setTimeout(function() { if ((Date.now() - lastRan) >= limit) { func.apply(context, args) lastRan = Date.now() } }, limit - (Date.now() - lastRan)) } } } // код будет срабатывать раз в 1 секунду document.addEventListener('scroll', throttle(function() { return console.log('Hey! It is', new Date().toUTCString()) }, 1000))
Уменьшающаяся при прокрутке «шапка» страницы без JavaScript
Представьте себе красивую и массивную «шапку» (header) веб-страницы с множеством отступов сверху и снизу от содержимого. Когда страница прокручивается (скроллится) вниз, «шапка» сжимается, уменьшая отступы и содержимое, чтобы оставить больше места на экране для остального контента.
Обычно, чтобы добавить такой эффект уменьшения шапки при скролле страницы, используется немного JavaScript и CSS, но с появлением position: sticky
то же самое можно сделать, используя только CSS.
Начинаем, как обычно, с HTML-разметки. Здесь нет ничего сложного: <header>
с одним потомком
<div>
, который, содержит логотип и навигацию.<header> <div> <div>...</div> <nav>...</nav> </div> </header>
Затем в CSS, объявим высоту для <header>
(120 пикселей) и настроим его как flex-контейнер, который выравнивает содержимое по центру. Затем сделаем его «липким» (sticky).
.header-outer { display: flex; align-items: center; position: sticky; height: 120px; }
Все остальные элементы «шапки»: логотип и навигация — размещаются во внутреннем контейнере. В некотором смысле этот контейнер и является «шапкой», тогда как единственная функция родительского HTML-элемента
<header>
— обозначить её размеры, чтобы было что сокращать.
Настроим внутренний контейнер, указываем для .header-inner
высоту 70 пикселей и тоже делаем его «липким» (sticky).
.header-inner { height: 70px; position: sticky; top: 0; }
Для чего top: 0;
? Это нужно для того, чтобы контейнер, когда он становится «липким» (sticky), крепился к самому верху окна.
А теперь хитрость! Чтобы внутренний контейнер прилипал к верхнему краю страницы, нужно указать родительскому элементу <header>
отрицательное значение
top
, равное разнице высот между двумя контейнерами, чтобы он прилипал чуть выше окна. Это 70 пикселей минус 120 пикселей, так и напишем -50 пикселей..header-outer { display: flex; align-items: center; position: sticky; height: 120px; /* top равно разнице высот между внешним и внутренним контейнерами */ top: -50px; }
Собираем теперь это всё воедино. <header>
выдвигается за пределы экрана, а внутренний контейнер аккуратно помещается в верхней части области просмотра.
See this code Shrinking header on scroll without Javascript on x.xhtml.ru.
Таким образом можно приклеить к верхней части окна любой элемент. Например, важное объявление.
See this code Sticky banner on x.xhtml.ru.
При всём великолепии этого метода приклеивания элементов к верху окна при скролле с помощью только CSS, у него есть ограничения. Например, для внутреннего и внешнего контейнера нужно указать фиксированную высоту. При этом, они становятся уязвимыми для изменений, например, когда элементы навигации переносятся, потому что количество пунктов меню превышает количество отведенного для них места.
Еще одно ограничение? Не уменьшается логотип. Это, пожалуй, самый большой недостаток, поскольку логотипы часто являются самым большим потребителем свободного места. Наверное, когда-нибудь получится применять стили, основанные на липкости элемента…
How to Create a Shrinking Header on Scroll Without JavaScript.
position: sticky
Как плавно прокручивать страницу вниз с помощью JavaScript и CSS — Techstacker
Узнайте, как плавно прокручивать пользователя вниз длинной веб-страницы с помощью JavaScript и небольшого количества CSS.
Если вы хотите дать своим пользователям возможность плавно прокручивать страницу вниз, вы можете использовать свойство CSS scroll-behavior
и метод JavaScript scrollIntoView()
.
Вам потребуется следующее:
- длинная веб-страница с достаточным содержанием, чтобы активировать полосу прокрутки по оси Y в правой части браузера
- якорный элемент в верхней части страницы с идентификатором
- любой элемент с id внизу страницы
-
поведение прокрутки
свойство CSS -
свойство scrollIntoView()
JavaScript
Учимся на примерах!
Пример макета HTML
Вы можете использовать следующий пример разметки HTML для обучения (не стесняйтесь заменять фиктивными элементами
.
...
с реальным содержимым):....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
....
Вы достигли конца этой страницы!!
Обратите внимание, у нас есть один элемент привязки
вверху с идентификатором scroll-to-bottom
и один элемент внизу с идентификатором page-bottom
.
CSS
Чтобы активировать плавную прокрутку, добавьте в таблицу стилей CSS следующее:
html { поведение прокрутки: гладкое; } /* Макет */ главный { максимальная ширина: 700 пикселей; запас: 3рем авто; заполнение: 0 1rem; } # прокрутить вниз { вес шрифта: полужирный; цвет: зеленый; }
JavaScript
let scrollToBottom = document.querySelector("#scroll-to-bottom ") let pageBottom = document.querySelector("#page-bottom") scrollToBottom.addEventListener («щелчок», функция () { pageBottom.scrollIntoView() })
Как работает код JavaScript
- Сначала мы объявляем две переменные для ссылки
прокрутка вниз
истраница вниз
соответственно. - Затем мы присоединяем прослушиватель событий к переменной
scrollToBottom
и просим его специально прослушивать событий кликов. - Внутри
function() { .. }
мы присоединяем методscrollIntoView()
к нижнему элементу страницыpageBottom
.
Совместимость с браузером
10 лучших плагинов прокрутки одной страницы для мобильных устройств (обновление 2022 г.)
Что такое прокрутка одной страницы?
Лучший плагин для прокрутки одной страницы
Первоначально опубликовано 14 февраля 2019 г., обновлено 31 января 2022 г.
Лучшие плагины jQuery для прокрутки одной страницы
Создание полноэкранных веб-сайтов с прокруткой одной страницы с помощью fullPage.js
Автоматический переход к следующему разделу при прокрутке — SnapScroll
Плагин горизонтальной и вертикальной прокрутки одной страницы — jQuery fsscroll
Плагин JavaScript для плавной привязки прокрутки — panelSnap
Плагин jQuery для красивого веб-сайта с полноэкранной прокруткой — pagePiling.js
Лучшие ванильные плагины для прокрутки одной страницы на JavaScript
onepagescroll.

Облегченная библиотека JavaScript, упрощающая создание эффекта плавной прокрутки с помощью навигации по боковой странице. страничный веб-сайт / одностраничное приложение. Поддерживается навигация с помощью клавиатуры и сенсорные события.
Загрузка демо-версии
Библиотека JavaScript с точкой-навигация автоматически создает вертикальную боковую навигацию для веб-сайта с прокруткой одной страницы.
Загрузка демоверсии
fullPageScrollPureJS
Чистая реализация JavaScript/CSS для кросс-платформенной плавной прокрутки одной страницы без третьих зависимостей.
[Демо] [Скачать]
Библиотека навигации с простой прокруткой одной страницы – слайд-навигация
Легкий, простой в использовании плагин JavaScript, используемый для создания липкой навигации для ваших веб-страниц с прокруткой одной страницы.