Изучаем события в языке JavaScript

Раздел: Основы JavaScript -> События

Основы событий в JavaScript

События позволяют реагировать на действия пользователя или изменения в браузере. Главный способ назначения обработчика - метод addEventListener. Он даёт гибкость и контроль, поэтому считается базовым решением.

Рекомендуемый способ: addEventListener

Метод element.addEventListener(event, handler, options) позволяет назначить несколько обработчиков на одно событие, легко удалять их и управлять фазой распространения.


// Пример: кнопка с обработчиком клика
const btn = document.querySelector('#myButton');
btn.addEventListener('click', function(event) {
  console.log('Кнопка нажата');
});
  

Js event (события javascript)

Цель: универсальное и чистое назначение событий. Используется в большинстве современных проектов.

Как назначить обработчик через атрибут HTML?

В HTML можно написать onclick прямо в теге:


<button onclick="alert('Клик!')">Нажми меня</button>
  

события js (события javascript)

Этот способ удобен для быстрого прототипирования, но смешивает логику и представление, усложняет поддержку.

Типичные проблемы:

  • Можно назначить только один обработчик на событие.
  • Код в строке - плохая практика, трудно отлаживать.
  • Нельзя использовать this по контексту элемента (внутри атрибута this ссылается на глобальный объект в строгом режиме).

Как задать обработчик через свойство DOM?

Присвоить функцию свойству element.onclick:


const btn = document.getElementById('btn');
btn.onclick = function() {
  console.log('Нажато');
};
  

Подходит для простых сценариев, где нужен один обработчик.

Недостатки:

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

Как получить информацию о событии (объект Event)?

Внутри обработчика первый аргумент - объект события. Он содержит тип, координаты, нажатую клавишу и т.д.


document.addEventListener('keydown', (e) => {
  console.log('Нажата клавиша:', e.key);
});
  

Цель: доступ к деталям произошедшего действия. Обязательно нужно использовать в сложных интерактивных интерфейсах.

Ошибка: забыть параметр e, особенно при передаче другой функции.

Что такое всплытие и перехват событий?

Событие сначала проходит фазу перехвата (от window до цели), затем цель, затем всплывает обратно. По умолчанию обработчики срабатывают на фазе всплытия. Чтобы включить перехват, передайте {capture: true}.


document.body.addEventListener('click', () => console.log('body (всплытие)'), false);
document.body.addEventListener('click', () => console.log('body (перехват)'), {capture: true});
  

Цель: управление порядком выполнения обработчиков, реализация делегирования.

Путаница: если не указать capture, обработчик не сработает на фазе перехвата.

Как использовать делегирование событий?

Вместо назначения обработчика каждому элементу, вешаем один на родителя и проверяем event.target.


ul.addEventListener('click', function(e) {
  if (e.target.tagName === 'LI') {
    console.log('Клик по элементу списка:', e.target.textContent);
  }
});
  

Цель: снижение числа обработчиков, работа с динамически добавляемыми элементами.

Ошибка: забыть проверить target, обработчик сработает на все клики внутри родителя.

Как остановить выполнение других обработчиков?

Методы event.stopPropagation() и event.stopImmediatePropagation(). Первый предотвращает всплытие/перехват, но остальные обработчики на текущем элементе выполнятся. Второй останавливает все последующие обработчики на том же элементе.


div.addEventListener('click', (e) => {
  e.stopPropagation();
  console.log('Только на div');
});
  

Цель: изоляция поведения, управление очередностью.

Злоупотребление stopPropagation нарушает делегирование.

Как отменить действие браузера по умолчанию?

Использовать event.preventDefault(). Например, для ссылки, чтобы не переходить по адресу.


document.querySelector('a').addEventListener('click', (e) => {
  e.preventDefault();
  console.log('Переход отменён');
});
  

Цель: кастомизация поведения форм, ссылок, контекстного меню.

Забыть вызвать preventDefault - форма отправится, страница перезагрузится.

Как удалить обработчик события?

Использовать removeEventListener с той же функцией (требуется сохранение ссылки на неё).


function handler() { console.log('клик'); }
btn.addEventListener('click', handler);
// Позже
btn.removeEventListener('click', handler);
  

Цель: очистка памяти, отключение временного поведения.

Если функция анонимная, удалить её нельзя. Нужно сохранять ссылку.

Как добавить обработчик только один раз?

Передать опцию { once: true } в addEventListener.


btn.addEventListener('click', () => {
  console.log('Сработает ровно один раз');
}, { once: true });
  

Цель: ленивая инициализация, однократные действия.

Расширенные примеры работы с событиями

1. Обработка нескольких событий с одинаковой логикой

Можно передать массив типов событий или использовать общую функцию.

Пример

const input = document.querySelector('input');
['focus', 'blur', 'input'].forEach(type => {
  input.addEventListener(type, (e) => {
    console.log(`Событие ${type}`, e.target.value);
  });
});
  
(при фокусе, потере фокуса и вводе текста в консоли появится соответствующее сообщение)
  

2. Делегирование с учётом вложенных элементов

Проверка closest позволяет обрабатывать клики на любом уровне вложенности внутри контейнера.

Пример

const list = document.querySelector('ul');
list.addEventListener('click', (e) => {
  const li = e.target.closest('li');
  if (li && list.contains(li)) {
    console.log('Клик по:', li.textContent);
  }
});
  
(клик по любому li внутри ul выводит его текст; клик по пустому пространству игнорируется)
  

3. Использование фазы перехвата для приоритетной обработки

Обработчик на стадии перехвата может предотвратить выполнение других обработчиков.

Пример

document.addEventListener('click', (e) => {
  console.log('Перехват (документ)');
  e.stopPropagation(); // остановит всплытие, но не перехват
}, { capture: true });
  
(при клике в любом месте сначала выведется 'Перехват (документ)', затем события на цели, но всплытия не будет)
  

4. Генерация пользовательских событий (CustomEvent)

Создание события с передачей данных.

Пример

const event = new CustomEvent('userLogin', {
  detail: { username: 'John' }
});
document.addEventListener('userLogin', (e) => {
  console.log('Пользователь вошёл:', e.detail.username);
});
document.dispatchEvent(event);
  
Пользователь вошёл: John
  

5. Управление множеством обработчиков с помощью объекта options

Параметры once, passive, signal.

Пример

const controller = new AbortController();
window.addEventListener('scroll', () => {
  console.log('Скролл');
}, { passive: true, signal: controller.signal });
// Через некоторое время отмена
controller.abort();
  
(обработчик скролла будет вызван, но не помешает скроллингу; после abort удалён)
  

6. Обработка событий формы с валидацией

Предотвращение отправки при неверных данных.

Пример

document.querySelector('form').addEventListener('submit', (e) => {
  const input = e.target.querySelector('input[required]');
  if (!input.value.trim()) {
    e.preventDefault();
    console.log('Поле не заполнено');
  }
});
  
(если поле пустое - форма не отправляется, сообщение в консоли)
  

События JavaScript - comments

En
события js (javascript)