March 29

Click, Change, Load: что нужно знать дизайнеру о событиях на сайте

Я часто вижу, как дизайнеры создают красивые прототипы, но теряются, когда нужно объяснить логику интерактивности разработчикам. Если ты не разбираешься в верстке, но хочешь понимать, как сайт реагирует на действия пользователя — эта статья для тебя. Я расскажу про основные события вроде click или change, объясню, к каким элементам они привязаны и как это влияет на UX. Ты сможешь проектировать осознаннее и говорить с верстальщиками на одном языке — даже без знания JS.

1. События, которые ты точно встречал

Если ты проектируешь интерфейсы, ты де-факто уже работаешь с событиями — просто не называешь их так. Давай разберём 5 самых популярных событий, которые отвечают за базовую интерактивность.

1.1. click — «Кликнули? Делаем что-то!»

Где встречается
Кнопки (<button>), ссылки (<a>), карточки товаров, иконки.

Как работает
Срабатывает, когда пользователь кликает кнопкой мыши (или тапает на тачпаде или Enter при фокусе) по элементу на странице.

Типичный пример
Кнопка «Добавить в корзину» — событие срабатывает при любом клике (мышь, тап, Enter при фокусе).

Когда точно срабатывает

  • После отпускания кнопки мыши/тача (не при нажатии!).
  • При нажатии Enter/Space на элементе с фокусом (если это <button> или элемент с атрибутом role="button").

Менее популярные примеры

  1. Клик на лейбл (<label>)— переводит фокус на связанное поле ввода (<input>), но click сработает и на самом лейбле.
  2. Клик на SVG-иконке внутри кнопки — событие «всплывает» до родительской кнопки.
  3. Клик правой кнопкой мыши — тоже триггерит click (но обычно это перехватывают через contextmenu).

Пример из жизни Если в твоём макете есть карточка, которая должна вести на страницу товара, лучше обернуть её в <a>, а не назначать click на <div>.

1.2. change — «Значение изменилось? Обновляем!»

Где встречается Поля ввода (<input>), выпадающие списки (<select>), чекбоксы, другие контролы форм.

Как работает Срабатывает, когда пользователь изменил значение.

Типичный пример
Выбор страны в <select> — событие срабатывает только после завершения взаимодействия (например, закрытие выпадающего списка).

Когда точно срабатывает

  • Для <input type="text"> — при потере фокуса (blur), если значение изменилось.
  • Для <input type="checkbox"> — мгновенно при переключении.
  • Для <select> — после выбора пункта (даже если тот же пункт выбран повторно).

Менее популярные примеры

  1. <input type="file"> — при выборе файла (даже если отменили диалог и выбрали тот же файл).
  2. <input type="range"> — только после отпускания ползунка (в отличие от oinput).
  3. <textarea> — работает так же, как текстовый input, но дизайнеры часто забывают.

Что важно знать

  • Идеален для фильтров, форм и любых динамических данных — например, обновление цены при выборе варианта товара.
  • Не путай с input (реагирует на каждое нажатие клавиши).

Пример из жизни В Figma ты проектируешь селект с выбором страны. change сработает только после выбора, а не во время прокрутки списка.

1.3. focus / blur — «Куда нажали? Куда ушли?»

Где встречается Поля ввода (<input>), текстовые области (<textarea>).

Как работает

  • focus — когда пользователь тапнул/кликнул в поле,
  • blur — когда фокус потерялся (тапнул/кликнул в другое место).

Типичный пример
Поле ввода email — focus при клике внутрь, blur при клике вне поля.

Когда точно срабатывает

  • focus:
    • При клике/тапе.
    • При переходе клавишей Tab.
    • Программный вызов element.focus().
  • blur:
    • Только при полной потере фокуса (если внутри формы переключились на другое поле — сработает blur для первого и focus для второго).

Менее популярные примеры

  1. <div contenteditable="true"> — элемент с режимом редактирования тоже получает фокус, как поле ввода.
  2. focus на ссылке (<a>) — срабатывает при переходе по Tab, но игнорируется в большинстве интерфейсов.
  3. blur для <select> — если раскрыли список, но передумали и кликнули вне его.

Пример из жизни В макете формы входа ты добавляешь анимацию лейбла при фокусе — это как раз focus.

1.4. load — «Всё загрузилось? Показываем!»

Где встречается Изображения (<img>), вся страница (<body>), iframe.

Как работает Срабатывает, когда контент полностью загрузился.

Типичный пример
Изображение в галерее — событие срабатывает, когда весь контент (включая внешние ресурсы) загружен.

Когда точно срабатывает

  • Для изображений <img> — после полной загрузки изображения (даже если оно в кеше браузера).
  • Для скриптов <script> — после выполнения скрипта.
  • Для <iframe> — когда загружена вся вложенная страница.

Менее популярные примеры

  1. <link rel="stylesheet">load сработает после загрузки CSS.
  2. SVG, встроенный через <object> — событие для SVG-документа.
  3. Видео (<video>) — но чаще используют canplay (когда можно начать воспроизведение).

Что важно знать

  • Критично для лоадеров и «ленивой» загрузки — например, чтобы анимировать появление изображений.
  • Не перегружай страницу тяжёлыми скриптами в load — это замедлит отрисовку.

Пример из жизни: Ты делаешь лендинг с фоновым видео. load поможет запустить его только после загрузки, чтобы не ломать верстку.

1.5. submit — «Форма отправлена? Проверяем!»

Где встречается Формы (<form>)

Как работает Срабатывает при нажатии на кнопку отправки формы (<button type="submit"> или <input type="submit">) или Enter в поле.

Типичный пример
Форма входа — событие срабатывает перед отправкой данных на сервер.

Когда точно срабатывает

  • При клике на <button type="submit"> или <input type="submit">.
  • При нажатии Enter в любом поле формы (если нет кнопки type="button").
  • До фактической отправки — можно отменить через e.preventDefault().

Менее популярные примеры

  1. Форма без кнопки — сработает при Enter в любом input.
  2. Динамическая форма, созданная через JS — submit работает так же, как для обычной.
  3. <form method="dialog"> — для модальных окон в HTML5.

Что важно знать

  • Обязателено для валидации перед отправкой данных — например, проверка email.
  • Не забудь отменить стандартное поведение (e.preventDefault()), если страница не должна перезагружаться.

Пример из жизни В твоём макете есть форма подписки. submit — это момент, когда можно показать анимацию «Спасибо».

Как это пригодится тебе?

Теперь, когда ты знаешь эти события, ты можешь:

  1. Осознанно проектировать интерактивность — например, не требовать анимацию при click для <div>.
  2. Говорить с разработчиками на их языке — «Здесь нужен change, а не oinput».
  3. Избегать «невозможных» решений — если в твоём прототипе 10 событий mousemove, это может тормозить.

2. Что происходит с формами? События, которые управляют данными

Если ты проектируешь формы, тебе нужно понимать не только визуальные состояния (вроде «ошибка» или «успех»), но и какие события запускают эти изменения. Вот главные «триггеры», которые влияют на поведение полей ввода, чекбоксов и других элементов форм.

2.1. input — реакция на каждое нажатие

Типичный пример
Поле поиска с подсказками, где результаты обновляются по мере ввода.

Когда точно срабатывает

  • При каждом изменении значения (ввод символа, удаление, вставка из буфера).
  • Не ждёт потери фокуса — работает мгновенно.

Чем отличается от change?

  • change = «значение изменилось и подтверждено» (например, уход из поля).
  • input = «значение меняется прямо сейчас».

Менее популярные примеры

  1. Счётчик символов под полем комментария (обновляется при каждом нажатии).
  2. Динамическая валидация пароля (показывает силу пароля в реальном времени).
  3. Кастомные числовые поля (например, расчёт суммы при вводе цифр).

Совет для дизайнера
Если делаешь поле с мгновенной проверкой (например, поиск по базе), указывай в ТЗ:

«Использовать input, а не change — подсказки должны появляться сразу при вводе».

2.2. invalid — когда форма не отправляется

Типичный пример
Поле email с валидацией, которое подсвечивает ошибку, если введён некорректный адрес.

Когда точно срабатывает

  • При попытке отправить форму (submit), если поле не проходит встроенную HTML-валидацию (например, required или type="email").
  • Можно кастомизировать стандартное сообщение браузера.

Ограничение
Не работает, если валидация написана на JavaScript (только нативные проверки HTML5).

Менее популярные примеры

  1. Поле с ограничением по длине (minlength/maxlength).
  2. Числовое поле с min="0" (покажет ошибку при отрицательном значении).
  3. Кастомные стили ошибок — браузер показывает сообщение, но дизайн можно переопределить CSS.

2.3. reset — когда форма очищается

Типичный пример
Кнопка «Очистить форму» в фильтрах или настройках.

Когда точно срабатывает

  • Только при клике на <button type="reset"> или вызове form.reset().
  • Не срабатывает при ручной очистке поля (например, удалении текста).

Менее популярные примеры

  1. Многостраничная форма (например, анкета), где можно сбросить все введённые данные.
  2. Динамически создаваемые поля — если их добавили после загрузки страницы, reset тоже их очистит.
  3. Сброс фильтров в интернет-магазине без перезагрузки страницы.

Совет для дизайнера
Если в твоём макете есть кнопка «Очистить», уточни в ТЗ:

«Использовать reset, если нужно сбросить всю форму, или click с ручным очищением полей, если только часть».

Как это пригодится тебе?

  1. Для мгновенной реакции (поиск, подсчёт символов) → input.
  2. Для валидации при отправкеinvalid + submit.
  3. Для сброса формыreset.

Что дальше?
В следующей части я расскажу про события для сложных интерфейсов:

  • Как сделать анимацию при наведении (mouseover).
  • Как реагировать на прокрутку (scroll).
  • Почему dblclick — это почти всегда плохая идея.

3. События для сложных интерфейсов: hover, скролл и опасные кейсы

Теперь разберём события, которые оживляют современные интерфейсы — от плавных hover-эффектов до анимаций при прокрутке. Я объясню, как они работают, когда их стоит использовать, а когда лучше избегать.

3.1. mouseover / mouseout — «Навели курсор? Показываем подсказку!»

Типичный пример
Кнопка с выпадающей подсказкой при наведении.

Когда точно срабатывает

  • mouseover — когда курсор впервые попадает на элемент.
  • mouseout — когда курсор полностью покидает элемент (даже если перешёл на дочерний элемент!).

Подводные камни

  • На мобильных устройствах нет состояния наведения, поэтому такие эффекты должны дублироваться для тапов.
  • Если внутри элемента есть другие вложенные элементы, mouseout сработает при переходе на них (это можно исправить через mouseleave).

Менее популярные примеры:

  1. Интерактивная карта — подсветка регионов при наведении.
  2. Анимация иконки (например, вращение шестерёнки в настройках).
  3. Кастомные тултипы без использования CSS :hover.

Совет для дизайнера:
Если делаешь эффект наведения, продумай альтернативу для мобильных устройств:

«Использовать mouseover для десктопа, но добавить click для мобильных».

3.2. scroll — «Прокрутили страницу? Запускаем анимацию!»

Типичный пример
Появление блоков с текстом или изображениями по мере скролла (эффект «параллакс»).

Когда точно срабатывает

  • При любом перемещении скроллбара (включая инерцию на тач-устройствах).
  • Можно отлавливать прокрутку конкретного элемента (например, боковой панели), а не всей страницы.

Ограничения

  • Слишком частые вызовы scroll могут тормозить страницу (например, если внутри тяжёлые вычисления).
  • На iOS события скролла иногда срабатывают с задержкой.

Менее популярные примеры

  1. Бесконечная лента — подгрузка контента при достижении низа страницы.
  2. Фиксированное меню, которое меняет стиль после прокрутки на 100px.
  3. Кастомный скроллбар с анимацией.

Совет для дизайнера
Если хочешь анимацию при скролле, укажи в ТЗ:

«Оптимизировать scroll, чтобы не нагружать процессор (например, использовать throttling)».

3.3. dblclick — «Двойной клик? Почти никто не использует!»

Типичный пример
Редактор изображений, где двойной клик открывает полную версию.

Когда точно срабатывает

  • Только при быстрых последовательных кликах с интервалом < 300–500 мс (зависит от ОС).

Почему лучше избегать

  • 95% пользователей не ожидают двойного клика в интерфейсах.
  • На мобильных устройствах его почти невозможность.
  • Конфликтует с oclick (оба события сработают).

Менее популярные примеры

  1. Переименование файла в файловом менеджере (как в Windows).
  2. Открытие превью в админ-панели.
  3. Выделение текста — но это нативное поведение браузера.

Совет для дизайнера
Замени dblclick на:

  • Однократный клик + иконку действия (например, карандаш для редактирования).
  • Долгое нажатие (touchstart) для мобильных интерфейсов.

3.4. resize — «Изменили размер окна? Адаптируем макет!»

Типичный пример
Адаптивное меню, которое меняет layout при сужении экрана.

Когда точно срабатывает

  • При изменении размеров окна браузера (ручное растягивание, поворот устройства).
  • Не срабатывает при программном изменении размеров элемента (например, через JS).

Ограничения

  • Событие вызывается многократно при резизовом окне (нужен debounce).
  • На мобильных устройствах срабатывает при повороте экрана, но не при появлении/скрытии клавиатуры.

Менее популярные примеры

  1. Динамические диаграммы, которые пересчитывают размеры.
  2. Кастомные сетки с изменяемым количеством колонок.
  3. Отключение анимаций на узких экранах.

Совет для дизайнера
Если твой дизайн чувствителен к размерам экрана, добавь в ТЗ:

«Использовать resize с задержкой (debounce 200ms), чтобы избежать лагов».

Итог для дизайнера

  1. Hover-эффектыmouseover/mouseout (но продумай мобильную версию).
  2. Анимации при скроллеscroll (с оптимизацией!).
  3. Двойной клик → лучше не использовать (dblclick).
  4. Адаптация под размер экранаresizedebounce).

Ошибка, которую можно избежать
Не назначать scroll на тяжёлые операции (например, пересчёт позиций десятков элементов) — это приведёт к тормозам.

4. События для мобильных устройств: тапы, свайпы и особенности touch-интерфейсов

Если ты проектируешь мобильные приложения или адаптивные сайты, стандартные события вроде click и mouseover работают иначе — или не работают вообще. В этой главе я объясню, какие события заменяют привычные клики и ховеры на сенсорных экранах, и как это влияет на UX.

4.1. touchstart / touchend — аналог click, но для пальцев

Типичный пример
Кнопка, которая должна реагировать на касание, а не на клик.

Когда точно срабатывает

  • touchstart — в момент первого касания экрана (аналог mousedown).
  • touchend — когда палец отпускает экран (аналог mouseup).

Чем отличается от click?

  • click на мобильных имеет задержку ~300 мс (браузер ждёт, не будет ли двойного тапа).
  • touchstart срабатывает мгновенно, но не поддерживает hover-эффекты.

Менее популярные примеры:

  1. Игры (например, прыжок персонажа при касании).
  2. Интерактивные карты — выделение зоны при касании.
  3. Кастомные свайпы (но для них лучше использовать touchmove).

Совет для дизайнера:
Если нужна мгновенная реакция на тап, укажи в ТЗ:

«Использовать touchstart + touchend вместо click для мобильных».

4.2. touchmove — отслеживание движения пальца

Типичный пример
Галерея с горизонтальным свайпом.

Когда точно срабатывает

  • При движении пальца по экрану после touchstart.
  • Можно получить координаты касания (event.touches[0].clientX).

Ограничения

  • Событие срабатывает очень часто (нужна оптимизация, чтобы избежать лагов).
  • Не работает при попытке свайпать скролл страницы.

Менее популярные примеры

  1. Рисование пальцем (как в графических редакторах).
  2. Перетаскивание элементов (drag-and-drop).
  3. Управление громкостью (вертикальный свайп).

Совет для дизайнера:
Если делаешь интерфейс со свайпами, продумай:

«Добавить визуальную подсказку (например, точки для свайпа в галерее), так как не все пользователи ожидают этого жеста».

4.3. gesturestart / gesturechange — масштабирование и поворот

Типичный пример
Изображение, которое можно увеличить двумя пальцами (пинч-зум).

Когда точно срабатывает

  • При мультитач-жестах (двумя и более пальцами).
  • Позволяет отслеживать масштаб (event.scale) и угол поворота (event.rotation).

Ограничения

  • Работает только на iOS и некоторых Android-устройствах.
  • Требует отмены стандартного поведения (event.preventDefault()), иначе браузер будет масштабировать всю страницу.

Менее популярные примеры

  1. 3D-модели с поворотом.
  2. Интерактивные инфографики (например, схема здания).
  3. Кастомные карты с зумом.

Совет для дизайнера:
Если проектируешь пинч-зум, укажи:

«Заблокировать стандартное масштабирование страницы через <meta name="viewport" content="user-scalable=no">».

4.4. orientationchange — поворот экрана

Типичный пример
Видеоплеер, который переключается между портретным и ландшафтным режимом.

Когда точно срабатывает

  • Только при изменении ориентации устройства (не при программном повороте элемента).
  • Можно проверить новое положение через window.orientation.

Ограничения

  • Не срабатывает на ПК (только мобильные устройства).
  • На iOS иногда игнорируется, если страница загружена в iframe.

Менее популярные примеры

  1. Карусели, которые меняют количество слайдов при повороте.
  2. Адаптивные таблицы, преобразующиеся в карточки.
  3. Игры с разным управлением в портрете/ландшафте.

Совет для дизайнера
Всегда тестируй интерфейс в обоих ориентациях:

«При повороте экрана (orientationchange) перестраивать сетку галереи с 2 на 4 колонки».

Итог для дизайнера

  1. Быстрые тапыtouchstart / touchend.
  2. Свайпыtouchmove (но избегай лагов).
  3. Пинч-зумgesturechange (только для iOS/Android).
  4. Поворот экранаorientationchange.

Ошибка, которую можно избежать
Не полагаться только на click для мобильных — это вызовет задержку 300 мс.

5. Специальные события: жесты, анимации и неочевидные сценарии

Теперь разберём события, которые оживляют интерфейсы — от сложных жестов до анимаций и работы с мультимедиа. Эти знания помогут тебе проектировать по-настоящему динамичные интерфейсы, не нарушая UX.

5.1. animationstart / animationend — контроль CSS-анимаций

Типичный пример
Кнопка, которая плавно исчезает после отправки формы.

Когда точно срабатывает

  • animationstart — в первый кадр анимации (даже если она на паузе).
  • animationend — когда анимация полностью завершена (или отменена).

Важные нюансы

  • Не путай с transitionend (для CSS-переходов).
  • Если анимация прервана (например, удалён класс), animationend не сработает.

Менее популярные примеры

  1. Каскадные анимации — когда завершение одной запускает другую.
  2. Скрытие элемента только после окончания анимации.
  3. Счётчик повторов анимации через animationiteration.

Совет для дизайнера
Если анимация критична для UX, укажи:

«Элемент должен стать кликабельным только после animationend».

5.2. fullscreenchange — вход/выход в полноэкранный режим

Типичный пример
Видеоплеер с кнопкой полноэкранного режима.

Когда точно срабатывает

  • При любом изменении состояния: как при входе в fullscreen, так и при выходе.
  • Работает для видео, карт, игр и даже отдельных div-блоков.

Ограничения

  • Требует ручного вызова API (element.requestFullscreen()).
  • В iOS Safari работает с ограничениями.

Менее популярные примеры

  1. Презентации с полноэкранными слайдами.
  2. Фотогалереи без интерфейса в fullscreen.
  3. Скрытие панели инструментов при максимальном размере.

Совет для дизайнера
Всегда предусматривай кнопку выхода:

«При fullscreenchange показывать overlay с крестиком в углу».

5.3. beforeunload — «Точно хотите уйти?»

Типичный пример
Предупреждение при попытке закрыть страницу с несохранёнными данными.

Когда точно срабатывает

  • При закрытии вкладки, переходе по ссылке или обновлении страницы.
  • Можно кастомизировать стандартное браузерное сообщение.

Ограничения

  • Современные браузеры показывают только дефолтный текст (нельзя вставить свою верстку).
  • Не работает в мобильных браузерах.

Менее популярные примеры

  1. Автосохранение черновика перед уходом.
  2. Отслеживание времени на странице.
  3. Очистка кеша при выходе.

Совет для дизайнера
Не злоупотребляй этим событием:

«Использовать beforeunload только для критичных данных (например, незавершённый заказ)».

5.4. error — когда что-то пошло не так

Типичный пример
Запасное изображение, если основное не загрузилось.

Когда точно срабатывает

  • Для <img> — при ошибке загрузки (неверный URL, 404).
  • Для <script> — если скрипт не удалось выполнить.
  • Для window — при необработанных ошибках JavaScript.

Менее популярные примеры

  1. Кастомные прелоадеры для видео (<video onerror=...>).
  2. Аналитика ошибок через отправку данных на сервер.
  3. Резервный шрифт при проблемах с загрузкой основного.

Совет для дизайнера
Продумай fallback-состояния:

«Для всех изображений добавить error с заменой на placeholder».

Итог для дизайнера

  1. Анимацииanimationstart/animationend.
  2. Fullscreenfullscreenchange (но тестируй на iOS).
  3. Предупреждения при уходеbeforeunload (экономно!).
  4. Обработка ошибокerror + fallback-дизайн.

Ошибка, которую можно избежать:
Не назначать beforeunload для тривиальных действий (например, «Точно хотите уйти?») — это раздражает пользователей.

6. Другие неохваченные события

  • События клавиатуры
    • keypress (устаревшее, лучше keydown/keyup)
    • Комбинации клавиш (Ctrl+C, Enter).
  • События буфера обмена
    • copy, paste, cut — например, для запрета копирования контента.
  • События drag-and-drop
    • dragstart, drop — для перетаскивания файлов в интерфейс.
  • События видимости страницы
    • visibilitychange — если вкладка стала неактивной (например, для паузы в видео).