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

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

7 min read Web‑разработка Обновлено 17 Apr 2026
addEventListener в JavaScript — прослушивание событий
addEventListener в JavaScript — прослушивание событий

Этот материал объясняет, как с помощью addEventListener() получать и обрабатывать DOM-события в JavaScript: мышинные и клавиатурные события, делегация, управление распространением и параметры addEventListener. Включены практические примеры, методы повышения производительности и контроль ошибок.

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

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

Что такое событийно-ориентированное программирование

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

Кратко: событие — это уведомление о том, что «что-то случилось»; обработчик (listener) — функция, которая выполняется в ответ на это событие.

Что такое обработчик событий (event listener)

Обработчик событий — это функция, запускаемая при возникновении конкретного события. Обработчик «слушает» элемент и вызывает заранее определённую логику, когда событие происходит. Типичные события: клики мыши, нажатия клавиш, изменение размеров окна, изменение значения поля ввода и т. п.

Как создать обработчик с помощью addEventListener

В DOM можно прослушивать события на любом элементе. У всех объектов, поддерживающих события (window, document, элементы), есть метод addEventListener(), унаследованный от интерфейса EventTarget.

Базовый синтаксис:

element.addEventListener("event", functionToExecute);

Где:

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

Создадим простую страницу с несколькими элементами:

  
  
  
      
    Document  
  
  
      
        

Welcome

        

           Hello, welcome to my website.         

             
             User Info         User Name:                       
    

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

Файл app.js — простой пример

document.querySelector('.btn').addEventListener("click", clickDemo)  
  
function clickDemo(){  
    console.log("Hi there")  
}

Этот код находит первый элемент с классом .btn и добавляет обработчик для события “click”. При клике в консоль браузера будет выводиться “Hi there”.

Связанный материал: как использовать селекторы DOM (querySelector, querySelectorAll, getElementById).

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

Мышинные события

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

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

Событие click срабатывает при нажатии и отпускании кнопки мыши над элементом. dblclick — при двух быстрых кликах. Можно назначать несколько обработчиков на один элемент: addEventListener поддерживает множественные подписки для одного и того же события.

Пример: dblclick

document.querySelector('.btn').addEventListener("dblclick", dblclickDemo)  
  
function dblclickDemo(){  
    alert("This is a demonstration of how to create a double-click event")  
}

После добавления выше вы получите alert при двойном клике. Поскольку двойной клик по сути содержит два click-события, оба обработчика (click и dblclick) могут быть вызваны в одном действии, если они оба подключены.

Оповещение браузера после двойного клика

Когда мышинные события не подходят

Важно: на мобильных устройствах событийная модель отличается — вместо mousemove/mousedown часто используются touchstart, touchmove, touchend. Для поддержания кросс-платформенного UX используйте Pointer Events (pointerdown/pointerup) или отдельную обработку touch-событий.

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

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

  • keydown срабатывает при нажатии клавиши
  • keyup — при отпускании

Лучшее место для привязки — конкретный элемент ввода (input, textarea) или document, если нужно глобальное поведение.

Пример: чтение значения поля

let greetings = document.querySelector('p');  
document.querySelector('input').addEventListener("keyup", captureInput)  
  
function captureInput(e){  
    greetings.innerText = (`Hello ${e.target.value}, welcome to my website.`)  
}

Этот обработчик обновляет текст абзаца при каждом отпускании клавиши, подставляя текущее значение поля. Параметр e — объект события, у которого есть свойство target, ссылающееся на элемент-источник.

Результат события keyup: обновлённый абзац

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

addEventListener принимает третий необязательный аргумент — options или useCapture. Начиная с современных спецификаций, удобно передавать объект options, в котором есть общие поля:

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

Пример с options:

element.addEventListener('scroll', onScroll, { passive: true })

Пассивные обработчики полезны для оптимизации прокрутки: браузер знает, что handler не будет препятствовать стандартному поведению, и может выполнять оптимизации.

Фазы распространения

Событие проходит три основные фазы:

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

По умолчанию обработчики работают на этапе всплытия (capture: false). Если нужно вмешаться раньше, используйте capture: true.

Примеры остановки распространения

child.addEventListener('click', function(e) {
  e.stopPropagation(); // остановит дальнейшее всплытие
});

parent.addEventListener('click', function(e) {
  console.log('Родительский обработчик');
});

stopImmediatePropagation() дополнительно предотвращает вызов других обработчиков на том же элементе.

Важно: злоупотребление остановкой распространения делает код сложным для поддержки. Предпочитайте делегирование и ясную архитектуру событий.

Делегация событий (Event Delegation)

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

Пример делегации:

const list = document.querySelector('#list');
list.addEventListener('click', (e) => {
  const item = e.target.closest('.item');
  if (!item) return;
  // обработка click для элемента .item
});

Делегация эффективна, когда элементы создаются динамически или когда нужно минимизировать число подписок.

Удаление обработчиков и управление памятью

Чтобы убрать обработчик, используйте removeEventListener, передав ту же функцию-референс и те же опции capture:

function handler(e) { /* ... */ }
button.addEventListener('click', handler);
button.removeEventListener('click', handler);

Если использовать анонимную функцию в addEventListener, её нельзя будет удалить через removeEventListener, поэтому храните ссылку на функцию, если планируете её снять.

Памятные советы:

  • Удаляйте обработчики для тяжёлых элементов при удалении из DOM
  • Для одноразовых задач используйте { once: true }

Производительность: throttle, debounce и passive

Частые события (scroll, resize, mousemove) могут генерировать сотни вызовов в секунду. Для них используйте:

  • debounce — запускать обработчик спустя задержку после последнего события
  • throttle — вызывать обработчик не чаще, чем N раз в секунду

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

Доступность и надежность

  • Всегда думайте о клавиатурных сценариях: обеспечьте функциональность через клавиатуру (Enter, Space) и управляйте фокусом
  • Не полагайтесь только на мышиные события — поддерживайте touch и pointer events
  • Для интерактивных контролов используйте semantic HTML (button, a, input) и ARIA, когда нужно

Безопасность и приватность

  • В обработчиках событий не храните чувствительные данные в глобальных переменных
  • Следите за тем, какие данные отправляете на сервер через события ввода — соблюдайте правила приватности и минимизируйте передачу персональных данных

Когда addEventListener не подходит

Мини‑методология: как надёжно внедрять обработчики

  1. Определите точку привязки: конкретный элемент или контейнер для делегации
  2. Напишите чистую функцию-обработчик, принимающую event
  3. Ограничьте частоту вызовов (throttle/debounce) для частых событий
  4. Добавьте { passive: true } для событий прокрутки/тача, если не вызываете preventDefault
  5. Тестируйте клавиатуру и мобильные устройства
  6. Удалите обработчики при уничтожении компонента

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

Дерево принятия решения (Mermaid)

flowchart TD
  A[Нужно ли обрабатывать событие?] --> B{Много похожих элементов?}
  B -- Да --> C[Применить делегацию на родителе]
  B -- Нет --> D[Привязать обработчик к элементу]
  C --> E{Событие частое?}
  D --> E
  E -- Да --> F[Добавить throttle/debounce]
  E -- Нет --> G[Обычный обработчик]
  F --> H{Нужно ли preventDefault?}
  G --> H
  H -- Да --> I[passive: false или по умолчанию]
  H -- Нет --> J[passive: true]

Краткий словарь терминов

Шаблон проверок (Acceptance)

Заключение

addEventListener — базовый и мощный инструмент для работы с событиями в браузере. Понимание фаз распространения, опций (capture, once, passive), делегации и контроля частоты вызовов позволяет писать производительный, надёжный и доступный код. При проектировании событийной логики думайте о переносимости (мобильные устройства), доступности и безопасности данных.

Кратко:

Примечание: используйте removeEventListener с той же ссылкой на функцию и теми же опциями, чтобы корректно отписываться от событий.

Автор
Редакция

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

Лучшие виджеты для iPhone — обзор и инструкция
iPhone

Лучшие виджеты для iPhone — обзор и инструкция

Темы WordPress: выбор, установка, управление
WordPress

Темы WordPress: выбор, установка, управление

KVM на Arch Linux: установка и первая виртуальная машина
Виртуализация

KVM на Arch Linux: установка и первая виртуальная машина

Эффект Зейгарник для продуктивности
Продуктивность

Эффект Зейгарник для продуктивности

Ремонт ноутбука: диагностика и практические советы
Ремонт техники

Ремонт ноутбука: диагностика и практические советы

Безопасное выключение Raspberry Pi
Raspberry Pi

Безопасное выключение Raspberry Pi