\n```\n\n**Результат при клике на кнопку:**\n```\nКнопка кликнута!\nРодитель кликнут!\n```\n\nПочему? Событие **всплывает** (bubbles) вверх! Сначала обработчик кнопки, потом обработчик родителя.\n\n### Использование stopPropagation()\n\n```html\n
\n \n
\n\n\n```\n\n**Результат при клике на кнопку:**\n```\nКнопка кликнута!\n```\n\nРодитель НЕ получит событие, потому что мы остановили всплытие!\n\n### Практические примеры\n\n#### 1. Модальные окна (dropdown, popup)\n\n```html\n
\n \n \n
\n\n\n```\n\n#### 2. Делегирование событий в списке\n\n```html\n\n\n\n```\n\nБез `stopPropagation()` на кнопке удаления, отработал бы и `delete` и `select`!\n\n#### 3. React компонент с stopPropagation\n\n```javascript\nimport React from 'react';\n\nfunction Card() {\n const handleCardClick = () => {\n console.log('Карточка кликнута');\n // Переход на деталь\n };\n\n const handleDeleteClick = (e) => {\n e.stopPropagation(); // Не даём родителю обработать!\n console.log('Удаляем карточку');\n // API запрос на удаление\n };\n\n const handleLikeClick = (e) => {\n e.stopPropagation();\n console.log('Лайк!');\n };\n\n return (\n
\n

Заголовок

\n

Описание

\n \n \n \n
\n );\n}\n```\n\n### stopPropagation vs preventDefault\n\n```javascript\nconst button = document.querySelector('button[type=\"submit\"]');\n\nbutton.addEventListener('click', (event) => {\n // stopPropagation — останавливает всплытие\n // Не переходит на родителя\n event.stopPropagation();\n \n // preventDefault — отменяет поведение браузера\n // Форма НЕ отправится\n event.preventDefault();\n});\n```\n\n| Метод | Что делает | Когда использовать |\n|-------|-----------|-------------------|\n| **stopPropagation()** | Останавливает всплытие события | Когда нужно, чтобы родитель НЕ обработал событие |\n| **preventDefault()** | Отменяет стандартное поведение | Когда нужно остановить навигацию, отправку формы и т.д. |\n| **stopImmediatePropagation()** | Останавливает ВСЕ обработчики | Когда нужна максимальная изоляция |\n\n### Иерархия событий: полный пример\n\n```html\n
\n
\n \n
\n
\n\n\n```\n\n**Порядок вывода:**\n```\nGrandparent capturing\nParent capturing\nChild capturing\nChild bubbling\nParent bubbling\nGrandparent bubbling\n```\n\n### Когда НЕ использовать stopPropagation()\n\n❌ **Антипаттерн** — использовать для скрытия ошибок в архитектуре\n\n```javascript\n// Плохо: stopPropagation как заплатка\nelement.addEventListener('click', (e) => {\n e.stopPropagation();\n // Это закрывает проблемы в коде\n});\n\n// Хорошо: правильная архитектура\n// Используй делегирование и правильную иерархию обработчиков\n```\n\n### Лучшие практики\n\n✅ Используй для **dropdown, modal, tooltip** — нужна изоляция\n✅ Используй при **делегировании событий** — разные действия на разных элементах\n✅ **React**: используй `e.stopPropagation()` в обработчиках\n✅ **Альтернатива**: правильная архитектура событий (не требует stopPropagation)\n\n### Современный подход в React\n\n```javascript\n// С React 17+ события отлично работают с stopPropagation\nfunction List() {\n return (\n \n );\n}\n```\n\nВывод: **stopPropagation() — критический инструмент** для управления событиями в интерактивных интерфейсах. Он позволяет создавать независимые компоненты, которые не мешают друг другу.","dateCreated":"2026-03-23T11:49:30.488491","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Для чего нужен метод stopPropagation?

1.0 Junior🔥 251 комментариев
#Браузер и сетевые технологии

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Метод stopPropagation()

stopPropagation() — это метод объекта события, который останавливает распространение события вверх по DOM дереву. Это критично для управления делегированием событий и предотвращения конфликтов.

Как работает распространение событий (Event Propagation)

Когда в браузере происходит событие (клик, ввод текста и т.д.), оно проходит три фазы:

  1. Capturing phase — событие идёт вниз от корня document к целевому элементу
  2. Target phase — событие достигает целевого элемента
  3. Bubbling phase — событие всплывает вверх от целевого элемента к document
document
  ↓ (capturing)
    html
      ↓ (capturing)
        body
          ↓ (capturing)
            div#parent
              ↓ (capturing)
                button (TARGET) ← клик здесь
              ↑ (bubbling)
            div#parent
          ↑ (bubbling)
        body
      ↑ (bubbling)
    html
↑ (bubbling)
document

Пример проблемы без stopPropagation()

<div id="parent">
  <button id="child">Нажми</button>
</div>

<script>
  // Обработчик на родителе
  document.getElementById('parent').addEventListener('click', () => {
    console.log('Родитель кликнут!');
  });

  // Обработчик на кнопке
  document.getElementById('child').addEventListener('click', () => {
    console.log('Кнопка кликнута!');
  });
</script>

Результат при клике на кнопку:

Кнопка кликнута!
Родитель кликнут!

Почему? Событие всплывает (bubbles) вверх! Сначала обработчик кнопки, потом обработчик родителя.

Использование stopPropagation()

<div id="parent">
  <button id="child">Нажми</button>
</div>

<script>
  document.getElementById('parent').addEventListener('click', () => {
    console.log('Родитель кликнут!');
  });

  // ОСТАНАВЛИВАЕМ распространение
  document.getElementById('child').addEventListener('click', (event) => {
    event.stopPropagation();
    console.log('Кнопка кликнута!');
  });
</script>

Результат при клике на кнопку:

Кнопка кликнута!

Родитель НЕ получит событие, потому что мы остановили всплытие!

Практические примеры

1. Модальные окна (dropdown, popup)

<div class="dropdown">
  <button class="dropdown-trigger">Меню</button>
  <div class="dropdown-menu">
    <a href="#">Пункт 1</a>
    <a href="#">Пункт 2</a>
  </div>
</div>

<script>
  // Закрывать меню при клике вне его
  document.addEventListener('click', () => {
    document.querySelector('.dropdown-menu').classList.remove('open');
  });

  // НО не закрывать при клике внутри меню
  document.querySelector('.dropdown-menu').addEventListener('click', (event) => {
    event.stopPropagation(); // Не даём событию всплыть!
  });

  // И открывать при клике на триггер
  document.querySelector('.dropdown-trigger').addEventListener('click', (event) => {
    event.stopPropagation(); // Не даём закрыться!
    document.querySelector('.dropdown-menu').classList.add('open');
  });
</script>

2. Делегирование событий в списке

<ul id="list">
  <li>
    <span>Элемент 1</span>
    <button class="delete">×</button>
  </li>
  <li>
    <span>Элемент 2</span>
    <button class="delete">×</button>
  </li>
</ul>

<script>
  // Делегирование: один обработчик на родителе
  document.getElementById('list').addEventListener('click', (event) => {
    if (event.target.classList.contains('delete')) {
      event.stopPropagation(); // Не переходим по li
      event.target.parentElement.remove();
      console.log('Элемент удалён');
    }
  });

  // Обработчик на li (выбор элемента)
  document.getElementById('list').addEventListener('click', (event) => {
    const li = event.target.closest('li');
    if (li) {
      console.log('Выбран:', li.textContent);
    }
  });
</script>

Без stopPropagation() на кнопке удаления, отработал бы и delete и select!

3. React компонент с stopPropagation

import React from 'react';

function Card() {
  const handleCardClick = () => {
    console.log('Карточка кликнута');
    // Переход на деталь
  };

  const handleDeleteClick = (e) => {
    e.stopPropagation(); // Не даём родителю обработать!
    console.log('Удаляем карточку');
    // API запрос на удаление
  };

  const handleLikeClick = (e) => {
    e.stopPropagation();
    console.log('Лайк!');
  };

  return (
    <div className="card" onClick={handleCardClick}>
      <h3>Заголовок</h3>
      <p>Описание</p>
      
      <button onClick={handleDeleteClick}>Удалить</button>
      <button onClick={handleLikeClick}>Лайк ❤</button>
    </div>
  );
}

stopPropagation vs preventDefault

const button = document.querySelector('button[type="submit"]');

button.addEventListener('click', (event) => {
  // stopPropagation — останавливает всплытие
  // Не переходит на родителя
  event.stopPropagation();
  
  // preventDefault — отменяет поведение браузера
  // Форма НЕ отправится
  event.preventDefault();
});
МетодЧто делаетКогда использовать
stopPropagation()Останавливает всплытие событияКогда нужно, чтобы родитель НЕ обработал событие
preventDefault()Отменяет стандартное поведениеКогда нужно остановить навигацию, отправку формы и т.д.
stopImmediatePropagation()Останавливает ВСЕ обработчикиКогда нужна максимальная изоляция

Иерархия событий: полный пример

<div id="grandparent">
  <div id="parent">
    <button id="child">Нажми</button>
  </div>
</div>

<script>
  const grandparent = document.getElementById('grandparent');
  const parent = document.getElementById('parent');
  const child = document.getElementById('child');

  // CAPTURING фаза
  grandparent.addEventListener('click', () => {
    console.log('Grandparent capturing');
  }, true); // true = capturing phase

  parent.addEventListener('click', () => {
    console.log('Parent capturing');
  }, true);

  child.addEventListener('click', () => {
    console.log('Child capturing');
  }, true);

  // BUBBLING фаза (default)
  child.addEventListener('click', () => {
    console.log('Child bubbling');
  });

  parent.addEventListener('click', () => {
    console.log('Parent bubbling');
  });

  grandparent.addEventListener('click', () => {
    console.log('Grandparent bubbling');
  });
</script>

Порядок вывода:

Grandparent capturing
Parent capturing
Child capturing
Child bubbling
Parent bubbling
Grandparent bubbling

Когда НЕ использовать stopPropagation()

Антипаттерн — использовать для скрытия ошибок в архитектуре

// Плохо: stopPropagation как заплатка
element.addEventListener('click', (e) => {
  e.stopPropagation();
  // Это закрывает проблемы в коде
});

// Хорошо: правильная архитектура
// Используй делегирование и правильную иерархию обработчиков

Лучшие практики

✅ Используй для dropdown, modal, tooltip — нужна изоляция ✅ Используй при делегировании событий — разные действия на разных элементах ✅ React: используй e.stopPropagation() в обработчиках ✅ Альтернатива: правильная архитектура событий (не требует stopPropagation)

Современный подход в React

// С React 17+ события отлично работают с stopPropagation
function List() {
  return (
    <ul onClick={(e) => {
      if (e.target.className === 'delete-btn') {
        e.stopPropagation();
        // Удаляем
      } else {
        // Выбираем элемент
      }
    }}>
      {/* items */}
    </ul>
  );
}

Вывод: stopPropagation() — критический инструмент для управления событиями в интерактивных интерфейсах. Он позволяет создавать независимые компоненты, которые не мешают друг другу.