События, классы и их продолжительность:
| Событие | Класс на <body> | Тип | Продолжительность | |
|---|---|---|---|---|
| DOMContentLoaded | DOM построен | is-dom-ready |
постоянный | до конца сессии |
| load | страница загружена | is-loaded |
постоянный | до конца сессии |
| scroll | прокрутка страницы | is-scrolling |
pulse | 0.5 с после остановки |
| click | клик в любом месте | is-clicking |
pulse | 0.5 с |
| mousemove | движение мыши | is-mousemoving |
pulse | 0.5 с после остановки |
| touchstart | касание экрана | is-touching |
pulse | 0.5 с |
| - | бездействие 30 с | is-idle |
постоянный | до любого действия |
JS:
Скрипт подключается один раз на весь сайт. Он не трогает элементы напрямую — только переключает классы на <body>. Всё остальное делается на CSS.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
(function () { 'use strict'; // настройки const SCROLL_MS = 500; const CLICK_MS = 500; const MOUSEMOVE_MS = 500; const TOUCH_MS = 500; const IDLE_MS = 30000; const body = document.body; const timers = {}; // pulse — класс на N мс function pulse(cls, ms) { body.classList.add(cls); clearTimeout(timers[cls]); timers[cls] = setTimeout(function () { body.classList.remove(cls); }, ms); } // постоянные классы if (document.readyState !== 'loading') { body.classList.add('is-dom-ready'); } else { document.addEventListener('DOMContentLoaded', function () { body.classList.add('is-dom-ready'); }); } window.addEventListener('load', function () { body.classList.add('is-loaded'); }); // pulse-классы window.addEventListener('scroll', function () { pulse('is-scrolling', SCROLL_MS); }, { passive: true }); window.addEventListener('mousemove', function () { pulse('is-mousemoving', MOUSEMOVE_MS); }, { passive: true }); window.addEventListener('touchstart', function () { pulse('is-touching', TOUCH_MS); }, { passive: true }); document.addEventListener('click', function () { pulse('is-clicking', CLICK_MS); }); // idle — свой таймер let idleTimer; function resetIdle() { body.classList.remove('is-idle'); clearTimeout(idleTimer); idleTimer = setTimeout(function () { body.classList.add('is-idle'); }, IDLE_MS); } ['mousemove', 'click', 'scroll', 'touchstart', 'keydown'].forEach(function (ev) { document.addEventListener(ev, resetIdle, { passive: true }); }); resetIdle(); })(); |
Примеры использования:
is-loaded — страница загружена
Класс появляется один раз после полной загрузки страницы. Удобно для скрытия прелоадера и плавного появления контента.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
body:not(.is-loaded) .preloader { opacity: 1; } body.is-loaded .preloader { opacity: 0; pointer-events: none; } body.is-loaded .entry-content { animation: fade-in 0.5s; } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } |
is-scrolling — прокрутка страницы
Класс висит, пока страница скроллится, и снимается через 0.5 с после остановки. Классический сценарий — «сжатие» шапки при скролле.
|
1 2 3 4 5 |
body.is-scrolling .header { padding: 8px 0; box-shadow: 0 2px 10px rgba(0,0,0,.1); transition: padding 0.3s, box-shadow 0.3s; } |
is-clicking — клик в любом месте
Класс появляется на 0.5 с при любом клике. Можно сделать «отзывчивость» интерфейса: элемент мягко реагирует на действие пользователя.
|
1 2 3 4 5 6 7 |
body.is-clicking .card { transform: translateY(-4px); transition: transform 0.15s; } body.is-clicking .btn { transform: scale(0.97); } |
is-mousemoving — движение мыши
Класс висит, пока курсор движется. Можно подсветить элементы или показать кастомный курсор.
|
1 2 3 4 5 6 |
body.is-mousemoving .custom-cursor { opacity: 1; } body.is-mousemoving .entry-content img { opacity: 0.85; } |
is-touching — касание экрана
Аналог клика, но для мобильных. Появляется на 0.5 с после касания.
|
1 2 3 |
body.is-touching .mobile-hint { opacity: 0; } |
is-idle — бездействие
Класс появляется через 30 секунд бездействия и снимается при любом действии. Можно приглушить интерфейс или показать подсказку «Вы здесь?».
|
1 2 3 4 5 6 7 |
body.is-idle .entry-content { opacity: 0.4; transition: opacity 0.5s; } body.is-idle .idle-hint { opacity: 1; } |
Комбинирование
Классы можно комбинировать. Например, показать что-то только когда страница загружена и пользователь скроллит:
|
1 2 3 |
body.is-loaded.is-scrolling .progress-bar { opacity: 1; } |
Наглядный пример:
Данный код в момент скролла cделает картинку ниже черно-белой, при клике/таче в любом месте страницы она будет подпрыгивать, при движении мышки становится прозрачной, а при бездействии 30 секунд пропадет вовсе.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
body .entry-content img { transition: 1s; } body.is-loaded.is-scrolling .entry-content img { filter: grayscale(1); } body.is-clicking .entry-content img, body.is-touching .entry-content img { animation: img-jump 0.3s ease; } @keyframes img-jump { 0% { transform: translateY(0); } 40% { transform: translateY(-12px); } 100% { transform: translateY(0); } } body.is-mousemoving .entry-content img { opacity: 0.8; } body.is-idle .entry-content img { opacity: 0; } |

Добавить комментарий: