События — это сердце интерактивности в вебе. Без них страница была бы статичной картинкой. Если вы хотите, чтобы кнопки реагировали на клики, формы отправлялись, а элементы менялись при наведении — вам нужно освоить работу с событиями. Эта статья поможет разобраться без головной боли.

Digital-студия WNDER

Что такое событие и зачем оно нужно

Событие — это сигнал о том, что что-то произошло. Например, пользователь кликнул по кнопке, навёл курсор на ссылку, нажал клавишу или страница полностью загрузилась. Браузер генерирует событие, а мы можем на него отреагировать, выполнив свой код.

Представьте, что вы сидите дома и ждёте звонка в дверь. Звонок — это событие. Ваша реакция (открыть дверь) — это обработчик. В JavaScript всё так же: есть событие, есть функция-обработчик, которая вызывается, когда событие происходит.

Способы повесить обработчик

Есть несколько способов назначить обработчик события на элемент. Рассмотрим три основных.

1. HTML-атрибут. Самый простой, но не самый чистый способ — прописать вызов функции прямо в атрибуте тега.

<button onclick="alert('Привет!')">Нажми меня</button>

Это работает, но смешивает разметку и логику. Плюс сложно поддерживать, если обработчиков много.

2. Свойство DOM-элемента. Можно присвоить функцию свойству onclick элемента.

const button = document.querySelector('button');
button.onclick = function() {
  alert('Привет!');
};

У этого способа есть ограничение: на одно событие можно повесить только один обработчик. Повторное присваивание перезапишет предыдущий.

3. addEventListener. Самый гибкий и современный метод. Позволяет добавлять несколько обработчиков на одно событие.

const button = document.querySelector('button');
button.addEventListener('click', function() {
  alert('Первый обработчик');
});
button.addEventListener('click', function() {
  alert('Второй обработчик');
});

Оба обработчика сработают по очереди. Это удобно, когда разные части кода должны реагировать на одно и то же событие.

Объект события и его свойства

Когда событие происходит, браузер создаёт объект события и передаёт его в обработчик первым аргументом. В этом объекте много полезной информации: какой элемент вызвал событие, координаты клика, нажатая клавиша и т.д.

Например, можно узнать, куда именно кликнули:

document.addEventListener('click', function(event) {
  console.log('Клик по координатам:', event.clientX, event.clientY);
});

Вот таблица с наиболее часто используемыми свойствами объекта события:

Свойство Описание
type Тип события (например, 'click')
target Элемент, на котором произошло событие
currentTarget Элемент, к которому привязан обработчик
clientX, clientY Координаты курсора относительно окна
key Нажатая клавиша (для событий клавиатуры)
preventDefault() Отменяет стандартное поведение браузера
Правило: Всегда используйте addEventListener вместо onclick и HTML-атрибутов. Это даёт гибкость, возможность удалить обработчик и не засоряет разметку.

Всплытие и погружение: как событие путешествует по DOM

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

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

Всплытие позволяет ловить события на родительских элементах. Например, если у вас есть список <ul> с множеством <li>, вы можете повесить один обработчик на <ul> и обрабатывать клики по любому пункту. Это называется делегированием событий.

const list = document.querySelector('ul');
list.addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    console.log('Выбран пункт:', event.target.textContent);
  }
});

Делегирование экономит память и упрощает код, особенно если элементов много или они добавляются динамически.

Если нужно, чтобы событие не всплывало дальше, вызовите event.stopPropagation(). Но используйте осторожно — это может сломать ожидаемое поведение других обработчиков.

Практические советы и лайфхаки

  • Удаляйте обработчики, когда они больше не нужны. Это предотвращает утечки памяти, особенно в одностраничных приложениях. Используйте removeEventListener с той же функцией, которую добавляли.
  • Используйте once: true в опциях addEventListener, если обработчик должен сработать только один раз. Например: element.addEventListener('click', handler, { once: true });
  • Для отладки удобно логировать объект события целиком — так вы увидите все доступные свойства и методы.
  • Не забывайте про event.preventDefault(), если нужно отменить стандартное действие (например, отправку формы или переход по ссылке).
  • Проверяйте event.target, чтобы понять, на каком именно элементе произошло событие, особенно при делегировании.
Лайфхак: Если вы динамически добавляете элементы на страницу, вешайте обработчик на родительский контейнер, который уже существует. Так вы избежите проблем с обработчиками на новых элементах.

Что в итоге

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

Практикуйтесь, экспериментируйте, и события станут вашими надёжными помощниками.

Студия WNDER