Learn JavaScript

События в DOM: addEventListener и объект event

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

1) addEventListener: базовая форма

const btn = document.querySelector(".btn");

btn.addEventListener("click", () => {
  console.log("Clicked");
});
  • “click” - имя события
  • функция - обработчик (handler), который запускается при событии

2) Объект event: что это

Обработчик получает объект event (часто пишут e). В нем лежит информация о том, что произошло.

const btn = document.querySelector(".btn");

btn.addEventListener("click", (event) => {
  console.log(event.type); // "click"
});

3) target и currentTarget

Это частая путаница:

  • event.target - элемент, по которому кликнули (самый “глубокий” внутри)
  • event.currentTarget - элемент, на котором висит обработчик

HTML:

<button class="btn"><span class="icon">+</span> Add</button>

JavaScript:

const btn = document.querySelector(".btn");

btn.addEventListener("click", (event) => {
  console.log(event.target);
  console.log(event.currentTarget);
});

Если кликнуть по span.icon, target будет span, а currentTarget останется button.

4) Получение данных из элемента

Часто данные берут из dataset:

HTML:

<button class="btn" data-id="42">Open</button>

JavaScript:

const btn = document.querySelector(".btn");

btn.addEventListener("click", (event) => {
  const id = event.currentTarget.dataset.id;
  console.log(id); // "42"
});

5) preventDefault: отмена стандартного действия

Некоторые элементы имеют стандартное поведение:

  • <a> переходит по ссылке
  • <form> отправляет форму и перезагружает страницу
  • <input> обрабатывает ввод

Чтобы остановить стандартное действие, используют event.preventDefault().

Пример: ссылка

const link = document.querySelector("a");

link.addEventListener("click", (event) => {
  event.preventDefault();
  console.log("Navigation canceled");
});

Пример: форма

const form = document.querySelector("form");

form.addEventListener("submit", (event) => {
  event.preventDefault();
  console.log("Form submit handled in JS");
});

6) События ввода: input и change

input срабатывает при каждом изменении значения (ввод/удаление).

const search = document.querySelector("input[type='search']");

search.addEventListener("input", (event) => {
  console.log(event.currentTarget.value);
});

change обычно срабатывает, когда ввод завершен (например, поле потеряло фокус) или при смене значения в select/checkbox.

const select = document.querySelector("select");

select.addEventListener("change", (event) => {
  console.log(event.currentTarget.value);
});

7) Клавиатура: keydown

document.addEventListener("keydown", (event) => {
  console.log(event.key);
});

Частый пример: обработка Escape.

document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") {
    console.log("Close");
  }
});

8) Снятие обработчика: removeEventListener

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

const btn = document.querySelector(".btn");

function onClick() {
  console.log("Clicked");
}

btn.addEventListener("click", onClick);

btn.removeEventListener("click", onClick);

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

9) Опции слушателя: once

Иногда нужно обработать событие только один раз.

const btn = document.querySelector(".btn");

btn.addEventListener(
  "click",
  () => {
    console.log("Only once");
  },
  { once: true }
);

Частые ошибки

1) Вызов функции вместо передачи

Неправильно:

const btn = document.querySelector(".btn");

function onClick() {
  console.log("Clicked");
}

btn.addEventListener("click", onClick());

Так onClick() выполнится сразу. Нужно передавать функцию, а не результат:

const btn = document.querySelector(".btn");

function onClick() {
  console.log("Clicked");
}

btn.addEventListener("click", onClick);

2) querySelector вернул null

Если элемента нет, попытка повесить слушатель даст ошибку.

const btn = document.querySelector(".missing");

if (btn) {
  btn.addEventListener("click", () => {
    console.log("ok");
  });
}

3) Путаница target/currentTarget

Если логика должна работать на кнопке, надежнее использовать currentTarget, а не target.

Что стоит запомнить

  • События подключают через addEventListener.
  • Обработчик получает объект event с деталями события.
  • target - где событие произошло, currentTarget - где висит обработчик.
  • preventDefault отменяет стандартное действие.
  • Чтобы снять обработчик, нужна ссылка на ту же функцию.