Гид по технологиям

Прослушивание событий в JavaScript

7 min read Frontend Обновлено 30 Dec 2025
Прослушивание событий в JavaScript — руководство
Прослушивание событий в JavaScript — руководство

Ноутбук с кодом на экране

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

Когда устройство создаёт событие, программа может «подслушать» его и выполнить соответствующее поведение. В этом руководстве вы научитесь слушать события с помощью JavaScript и строить устойчивую логику взаимодействия.

Что такое программирование, управляемое событиями

Event-driven programming — это парадигма, в которой выполнение логики привязано к событиям. Такую модель можно реализовать в любом языке высокого уровня, но она особенно распространена в средах с пользовательским интерфейсом, например в JavaScript в браузере.

Определение: событие — это объект, который описывает произошедшее действие (клик, ввод, изменение размера окна и т.д.).

Что такое слушатель событий

Слушатель событий — это функция, которая запускает заранее определённый процесс, когда зарегистрированное событие происходит. Проще: слушатель “слушает” действие, а затем вызывает функцию-обработчик.

События бывают разные: события мыши, клавиатуры, окна, формы, кастомные события и т.д.

Создание слушателя событий в JavaScript

Любой элемент в DOM может иметь слушатель. Для этого есть метод addEventListener(), который является методом интерфейса EventTarget. Объекты, которые поддерживают события, реализуют этот интерфейс — window, document и отдельные элементы страницы.

Простейшая структура вызова:

element.addEventListener("event", functionToExecute);

Где:

  • element — любой HTML-элемент (кнопка, параграф и т.д.)
  • “event” — строка с именем события
  • functionToExecute — ссылка на функцию-обработчик

Ниже создадим простую страницу с элементами для демонстрации слушателей:




    
    Документ


    

Добро пожаловать

Привет, добро пожаловать на мой сайт.

Информация о пользователе

Код выше создаёт простую страницу, которая подключает файл app.js. В этом файле будем добавлять слушатели.

Файл app.js — простой обработчик клика

document.querySelector('.btn').addEventListener("click", clickDemo);

function clickDemo(){
    console.log("Привет")
}

Этот код находит первую кнопку на странице через querySelector() и добавляет ей слушатель события “click”. При нажатии в консоли браузера появится строка “Привет”.

Связанный пример: как использовать селекторы DOM

Вывод при событии “click”

Вывод click события в консоли браузера

События мыши

Интерфейс MouseEvent представляет события, возникающие при взаимодействии пользователя с мышью. Частые примеры:

  • click
  • dblclick
  • mousemove
  • mouseover
  • mouseout
  • mouseup
  • mousedown

Событие click происходит, когда пользователь нажимает и отпускает кнопку мыши над элементом. dblclick — двойной клик, который по сути совмещает два click-события.

Важно: addEventListener позволяет навесить несколько слушателей на один элемент для разных событий.

Добавление dblclick для первой кнопки

document.querySelector('.btn').addEventListener("dblclick", dblclickDemo);

function dblclickDemo(){
    alert("Это демонстрация события двойного клика")
}

После добавления этого кода двойной клик по первой кнопке вызовет alert. Заметьте: двойной клик генерирует два click-события и одно dblclick, поэтому все слушатели при этом могут сработать.

Вывод dblclick: диалоговое окно alert и сообщения в консоли

Клавиатурные события

Интерфейс KeyboardEvent слушает взаимодействие с клавиатурой. На практике сейчас используются два события: keydown и keyup. Событие keypress помечено как deprecated и не рекомендуется.

  • keydown — происходит при нажатии клавиши
  • keyup — при отпускании клавиши

Лучший элемент для демонстрации — input поля.

Добавление слушателя клавиатуры в app.js

let greetings = document.querySelector('p');
document.querySelector('input').addEventListener("keyup", captureInput);

function captureInput(e){
    greetings.innerText = (`Привет ${e.target.value}, добро пожаловать на мой сайт.`)
}

Здесь мы получаем параграф и input, добавляем слушатель keyup, и при каждом отпускании клавиши обновляем текст в параграфе. Параметр e — объект события; его свойство target ссылается на элемент, с которым взаимодействовал пользователь.

Вывод keyup: параграф обновлён введённым именем

В примере выше при вводе имени параграф будет показывать введённое значение.

Параметры addEventListener и управление распространением событий

Метод addEventListener принимает третий необязательный параметр — options или useCapture (устаревшая форма). Параметры позволяют гибко управлять поведением слушателя:

  • capture (boolean) — если true, слушатель срабатывает на фазе захвата (capture), до фазы всплытия
  • once (boolean) — если true, слушатель удаляется автоматически после первого срабатывания
  • passive (boolean) — если true, сообщает браузеру, что обработчик не вызывает preventDefault(); полезно для прокрутки и повышения производительности

Пример с опциями:

button.addEventListener('click', handler, { capture: false, once: true, passive: false });

Важно: использование passive: true для событий прокрутки и touch-эвентов улучшит отзывчивость, потому что браузер не будет ждать возможного preventDefault().

Фазы события: захват и всплытие

Механика распространения события в DOM состоит из трёх фаз:

  1. Фаза захвата (capture) — событие идёт сверху вниз от document к целевому элементу.
  2. Целевая фаза — обработчики на целевом элементе.
  3. Фаза всплытия (bubble) — событие идёт от целевого элемента вверх к document.

По умолчанию addEventListener добавляет слушатель на фазе всплытия (bubble). Установив capture: true, вы подпишетесь на фазу захвата.

Если нужно остановить дальнейшее распространение события, используйте e.stopPropagation(). Чтобы отменить стандартное действие (например отправку формы по Enter), используйте e.preventDefault().

Делегирование событий (event delegation)

Делегирование — шаблон, при котором слушатель вешается на родительский контейнер вместо каждого дочернего элемента. Это экономит ресурсы и упрощает динамически добавляемые элементы.

Пример: у нас список кнопок внутри контейнера #about. Вместо навешивания слушателя на каждую кнопку — повесим один слушатель на контейнер:

document.getElementById('about').addEventListener('click', function(e){
    const btn = e.target.closest('.btn');
    if (!btn) return; // клик не по кнопке
    // обработка кнопки
    console.log('Нажата кнопка с id:', btn.id);
});

Плюсы:

  • меньше слушателей в DOM
  • подходит для динамических элементов

Ограничения и когда это не подходит:

  • сложнее срабатывание для событий, которые не всплывают
  • требуются дополнительные проверки целевого элемента (e.target)

Когда слушатели могут «подводить» — распространённые ошибки

  • Навесили слишком много слушателей на элементы с большой частотой событий (mousemove) — может быть медленно.
  • Использовали устаревшие события (keypress) — потеря кроссбраузерности.
  • Не учли порядок фаз и случайно остановили propagation там, где это мешает другим компонентам.
  • Делегирование не работает для событий, которые не всплывают (например focus) — используйте focusin/focusout или добавляйте слушатели напрямую.

Практические рекомендации по производительности и доступности

  • Используйте делегирование для большого числа однотипных элементов.
  • Для интенсивных событий (scroll, resize, mousemove) применяйте throttle/debounce или passive listeners.
  • Не полагайтесь только на события мыши — обеспечьте клавиатурный доступ и aria-атрибуты для доступности.
  • Проверяйте, не добавляете ли вы несколько идентичных слушателей (memory leak).

Важно: passive: true — хороший выбор для scroll и touch-обработчиков. Но если вам нужно preventDefault(), passive нельзя использовать.

Чек-листы по ролям

Frontend-разработчик:

  • Использовать делегирование, где это оправдано
  • Выбирать { once: true } для одноразовых действий
  • Применять passive для прокрутки
  • Тестировать в мобильных браузерах на touch-события

Тестировщик / QA:

  • Проверить клавиатурную навигацию (Tab, Enter, Space)
  • Проверить порядок срабатывания обработчиков
  • Проверить отмену действий (preventDefault) и stopPropagation

Продакт-менеджер:

  • Уточнить ожидаемое UX при двойных кликах и сочетаниях клавиш
  • Описать критерии приёмки для событий (см. ниже)

Критерии приёмки

  • Клик по кнопке вызывает требуемое действие и не приводит к лишним побочным эффектам.
  • Двойной клик выполняет свою задачу и не дублирует результаты от одиночного клика.
  • Ввод в поле обновляет UI в реальном времени без задержек.
  • Для динамически добавленных элементов обработчики работают корректно.

Набор тестов и сценариев (минимум)

  • Нажать, двойной клик, зажать и отпустить — проверить разные mouse-события.
  • Ввод текста в input — проверить keydown/keyup и корректность e.target.value.
  • Поставить passive слушатель на scroll — убедиться, что страница не тормозит.
  • Стоп распространения: добавить слушатель выше в DOM и проверить, останавливается ли propagation.

Шпаргалка: распространённые события (cheat sheet)

  • Клики: click, dblclick
  • Движение мыши: mousemove, mouseover, mouseout
  • Кнопки мыши: mousedown, mouseup
  • Клавиатура: keydown, keyup
  • Формы: submit, input, change
  • Окно: load, resize, scroll

Скорректированные примеры для реальных задач

  1. Обработчик один раз:
const btn = document.querySelector('.btn');
btn.addEventListener('click', handleOnce, { once: true });

function handleOnce(e){
  // выполнение только при первом клике
}
  1. Делегирование с проверкой роли кнопки:
document.body.addEventListener('click', (e) => {
  const btn = e.target.closest('[data-action]');
  if (!btn) return;
  const action = btn.dataset.action;
  // switch по action
});

Небольшая методология добавления событий в проект

  1. Определите гранулярность: прямой слушатель или делегирование.
  2. Выберите опции (capture/once/passive) исходя из сценария.
  3. Протестируйте на клавиатуре и мобильных устройствах.
  4. Покройте unit/e2e тестом критичные сценарии (ввод, клики, отправка).
  5. Мониторьте производительность и memory leaks.

Небольшой словарь (1‑строчно)

  • EventTarget — объект, поддерживающий события (window, document, элемент).
  • addEventListener — метод для подписки на событие.
  • propagation — распространение события по дереву DOM.
  • capture — фаза захвата события сверху вниз.
  • bubble — фаза всплытия события снизу вверх.

Заключение

Вы узнали основы прослушивания событий в браузере: как работает addEventListener, какие бывают mouse и keyboard события, как управлять фазами распространения и какие options доступны. Также рассмотрели делегирование, шаблоны проектирования для событий и практические рекомендации по производительности и доступности.

Краткие рекомендации:

  • Используйте делегирование для множества элементов
  • Применяйте passive для scroll/touch
  • Обязательно тестируйте клавиатурную доступность

Если нужно, в дополнение могу подготовить готовые шаблоны для популярных библиотек (React/Vue) или набор e2e-тестов для событий.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Raspberry Pi 3: установка и обновление
Raspberry Pi

Raspberry Pi 3: установка и обновление

Презентации в Figma — пошаговое руководство
Дизайн

Презентации в Figma — пошаговое руководство

Синхронизация света с музыкой для Хэллоуина
Освещение

Синхронизация света с музыкой для Хэллоуина

LED‑глаза на батарейках — простой DIY
Самодельные проекты

LED‑глаза на батарейках — простой DIY

Как сделать изображение резким — Photoshop, GIMP, онлайн
Фотография

Как сделать изображение резким — Photoshop, GIMP, онлайн

Кривые в Photoshop: руководство по тональному редактированию
Фотография

Кривые в Photoshop: руководство по тональному редактированию