\n```\n\n### Управление распространением события\n\n**stopPropagation()** — остановить распространение (но фаза продолжится)\n```javascript\nelement.addEventListener(\"click\", function(event) {\n event.stopPropagation();\n // Событие не пойдёт дальше по дереву DOM\n});\n```\n\n**stopImmediatePropagation()** — полная остановка\n```javascript\nelement.addEventListener(\"click\", function(event) {\n event.stopImmediatePropagation();\n // Другие обработчики на этом элементе не будут вызваны\n});\n```\n\n**preventDefault()** — отменить действие по умолчанию\n```javascript\nform.addEventListener(\"submit\", function(event) {\n event.preventDefault();\n // Форма не будет отправлена автоматически\n});\n```\n\n### Делегирование событий (Event Delegation)\n\nОсновная техника оптимизации — вешать обработчик на родителя вместо множества детей:\n\n```javascript\nconst list = document.getElementById(\"myList\");\n\nlist.addEventListener(\"click\", function(event) {\n const li = event.target.closest(\"li\");\n if (li) {\n console.log(\"Clicked item:\", li.textContent);\n }\n});\n```\n\nПреимущества:\n- Меньше памяти (один обработчик вместо многих)\n- Работает для динамически добавленных элементов\n- Упрощает управление\n\n### Особые события\n\n**Custom Events** — создание своих событий\n```javascript\nconst event = new CustomEvent(\"myEvent\", {\n detail: { message: \"Hello\" }\n});\n\nelement.addEventListener(\"myEvent\", (e) => {\n console.log(e.detail.message);\n});\n\nelement.dispatchEvent(event);\n```\n\n**Синтетические события в React** — React оборачивает события для кроссбраузерности:\n```javascript\nfunction Button() {\n const handleClick = (e) => {\n // e — это обёрнутый браузерный event\n console.log(e.nativeEvent); // доступ к оригинальному событию\n };\n return ;\n}\n```\n\n### Производительность\n\nПо умолчанию обработчики вызываются в фазе **всплывания**. Если нужна фаза захвата, используй третий параметр addEventListener():\n\n```javascript\n// Всплывание (по умолчанию)\nelement.addEventListener(\"click\", handler);\nelement.addEventListener(\"click\", handler, false);\n\n// Захват\nelement.addEventListener(\"click\", handler, true);\n```\n\nДля удаления обработчика нужна ссылка на функцию:\n```javascript\nconst handler = () => console.log(\"clicked\");\nelement.addEventListener(\"click\", handler);\nelement.removeEventListener(\"click\", handler);\n```\n\nПонимание механизма событий — ключевой навык для фронтенда. Правильное использование делегирования, управления распространением и кастомных событий делает код эффективнее и надёжнее.","dateCreated":"2026-04-02T22:19:48.185133","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как работает механизм событий в JavaScript?

1.0 Junior🔥 151 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм событий в JavaScript

Основные концепции

Событие (Event) — это сигнал о том, что произошло что-то важное. Пользователь кликнул по кнопке, загрузилась страница, произошла ошибка сети — все это события. JavaScript позволяет слушать эти события и реагировать на них через специальные функции-обработчики (event handlers).

Как браузер создаёт события

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

element.addEventListener("click", function(event) {
  console.log(event.type);        // "click"
  console.log(event.target);      // элемент, по которому кликнули
  console.log(event.currentTarget); // элемент, на котором слушатель
  console.log(event.timeStamp);   // время события
});

Регистрация обработчиков

Существует три способа добавить обработчик события:

  1. HTML-атрибут — не рекомендуется
<button onclick="handleClick()">Click me</button>
  1. Свойство DOM-элемента — работает, но ограничивает количество обработчиков
element.onclick = function() { console.log("clicked"); };
  1. addEventListener() — правильный способ
element.addEventListener("click", handleClick);
element.addEventListener("click", anotherHandler); // можно несколько обработчиков

Фазы распространения события (Event Bubbling & Capturing)

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

1. Capturing Phase (фаза захвата)

Событие идёт сверху вниз по дереву DOM, от окна к целевому элементу.

2. Target Phase (фаза цели)

Событие достигает целевого элемента.

3. Bubbling Phase (фаза всплывания)

Событие поднимается вверх по дереву DOM, от целевого элемента к окну.

<div id="outer">
  <div id="middle">
    <button id="inner">Click</button>
  </div>
</div>

<script>
const outer = document.getElementById("outer");
const middle = document.getElementById("middle");
const inner = document.getElementById("inner");

// Capturing phase (3-й параметр true)
outer.addEventListener("click", () => console.log("Outer capturing"), true);
middle.addEventListener("click", () => console.log("Middle capturing"), true);
inner.addEventListener("click", () => console.log("Inner capturing"), true);

// Bubbling phase (по умолчанию)
outer.addEventListener("click", () => console.log("Outer bubbling"));
middle.addEventListener("click", () => console.log("Middle bubbling"));
inner.addEventListener("click", () => console.log("Inner bubbling"));

// Порядок вывода:
// "Outer capturing"
// "Middle capturing"
// "Inner capturing"
// "Inner bubbling"
// "Middle bubbling"
// "Outer bubbling"
</script>

Управление распространением события

stopPropagation() — остановить распространение (но фаза продолжится)

element.addEventListener("click", function(event) {
  event.stopPropagation();
  // Событие не пойдёт дальше по дереву DOM
});

stopImmediatePropagation() — полная остановка

element.addEventListener("click", function(event) {
  event.stopImmediatePropagation();
  // Другие обработчики на этом элементе не будут вызваны
});

preventDefault() — отменить действие по умолчанию

form.addEventListener("submit", function(event) {
  event.preventDefault();
  // Форма не будет отправлена автоматически
});

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

Основная техника оптимизации — вешать обработчик на родителя вместо множества детей:

const list = document.getElementById("myList");

list.addEventListener("click", function(event) {
  const li = event.target.closest("li");
  if (li) {
    console.log("Clicked item:", li.textContent);
  }
});

Преимущества:

  • Меньше памяти (один обработчик вместо многих)
  • Работает для динамически добавленных элементов
  • Упрощает управление

Особые события

Custom Events — создание своих событий

const event = new CustomEvent("myEvent", {
  detail: { message: "Hello" }
});

element.addEventListener("myEvent", (e) => {
  console.log(e.detail.message);
});

element.dispatchEvent(event);

Синтетические события в React — React оборачивает события для кроссбраузерности:

function Button() {
  const handleClick = (e) => {
    // e — это обёрнутый браузерный event
    console.log(e.nativeEvent); // доступ к оригинальному событию
  };
  return <button onClick={handleClick}>Click</button>;
}

Производительность

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

// Всплывание (по умолчанию)
element.addEventListener("click", handler);
element.addEventListener("click", handler, false);

// Захват
element.addEventListener("click", handler, true);

Для удаления обработчика нужна ссылка на функцию:

const handler = () => console.log("clicked");
element.addEventListener("click", handler);
element.removeEventListener("click", handler);

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