← Назад к вопросам

Как остановить Bubbling после click?

2.2 Middle🔥 143 комментариев
#Soft Skills и рабочие процессы

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

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

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

Остановка Event Bubbling в JavaScript

Event Bubbling - это механизм, при котором событие сначала срабатывает на элементе, затем поднимается вверх по цепочке родительских элементов. Есть способы это остановить.

1. Метод stopPropagation()

Самый простой способ - использовать event.stopPropagation():

// HTML
// <div id="parent">
//   <button id="child">Нажми меня</button>
// </div>

const parent = document.getElementById('parent');
const child = document.getElementById('child');

// На кнопке
child.addEventListener('click', (event) => {
  console.log('Клик на кнопке');
  event.stopPropagation(); // Остановим всплытие
});

// На родителе
parent.addEventListener('click', (event) => {
  console.log('Клик на родителе');
});

// При клике на кнопку:
// Выведет только "Клик на кнопке"
// "Клик на родителе" НЕ выведется благодаря stopPropagation()

2. Отличие: stopPropagation vs preventDefault

Это часто путают, но это разные методы:

const form = document.querySelector('form');
const button = document.querySelector('button');

// stopPropagation() - останавливает всплытие события
button.addEventListener('click', (event) => {
  event.stopPropagation();
  // Событие click не поднимется выше
});

form.addEventListener('click', (event) => {
  console.log('Это НЕ выведется'); // Благодаря stopPropagation
});

// preventDefault() - отменяет стандартное действие
form.addEventListener('submit', (event) => {
  event.preventDefault();
  // Форма НЕ будет отправлена
});

3. stopImmediatePropagation() - ещё более сильный

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

const button = document.querySelector('button');

// Первый обработчик
button.addEventListener('click', (event) => {
  console.log('Первый обработчик');
  event.stopImmediatePropagation(); // Остановит всё
});

// Второй обработчик
button.addEventListener('click', (event) => {
  console.log('Второй обработчик'); // Это НЕ выведется
});

// На клик:
// Выведет только "Первый обработчик"

4. В React компонентах

В React это работает немного по-другому благодаря синтетическим событиям:

function MyComponent() {
  const handleChildClick = (e) => {
    console.log('Клик на child');
    e.stopPropagation(); // Остановим всплытие
  };

  const handleParentClick = (e) => {
    console.log('Клик на parent');
  };

  return (
    <div onClick={handleParentClick}>
      <button onClick={handleChildClick}>
        Нажми меня
      </button>
    </div>
  );
}

// При клике на кнопку выведет только "Клик на child"

5. Практический пример: закрытие модального окна

// HTML
// <div class="modal-overlay" id="overlay">
//   <div class="modal-content" id="content">
//     <button id="closeBtn">Закрыть</button>
//   </div>
// </div>

const overlay = document.getElementById('overlay');
const content = document.getElementById('content');
const closeBtn = document.getElementById('closeBtn');

// Закрыть модаль при клике на overlay
overlay.addEventListener('click', () => {
  overlay.style.display = 'none';
  console.log('Модаль закрыта');
});

// НЕ закрывать при клике на содержимое модали
content.addEventListener('click', (event) => {
  event.stopPropagation();
  console.log('Клик внутри модали, модаль не закрывается');
});

// Закрыть по кнопке
closeBtn.addEventListener('click', (event) => {
  event.stopPropagation();
  overlay.style.display = 'none';
});

6. Capturing фаза (обратное всплытие)

Есть также capturing фаза, которая происходит ДО события на целевом элементе:

const parent = document.getElementById('parent');
const child = document.getElementById('child');

// Третий параметр true = capturing фаза
parent.addEventListener('click', () => {
  console.log('Parent (capturing)');
}, true);

// Обычное всплытие
child.addEventListener('click', () => {
  console.log('Child');
}, false);

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

// При клике на child:
// Parent (capturing)
// Child
// Parent (bubbling)

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

Часто используют делегирование вместо stopPropagation():

// HTML
// <ul id="list">
//   <li class="item">Элемент 1</li>
//   <li class="item">Элемент 2</li>
//   <li class="item">Элемент 3</li>
// </ul>

const list = document.getElementById('list');

// Один обработчик для всех элементов
list.addEventListener('click', (event) => {
  if (event.target.classList.contains('item')) {
    console.log('Клик на:', event.target.textContent);
    // Не нужно stop Propagation, нам просто нужно узнать, что именно кликнули
  }
});

8. Сравнение методов

// stopPropagation()
event.stopPropagation();
// Останавливает всплытие события вверх по DOM
// Другие обработчики на том же элементе ещё выполнятся

// stopImmediatePropagation()
event.stopImmediatePropagation();
// Останавливает всплытие И другие обработчики на том же элементе
// Самый сильный способ

// preventDefault()
event.preventDefault();
// НЕ останавливает всплытие!
// Только отменяет стандартное действие (отправка формы, навигация по ссылке)

9. Живой пример: сложный сценарий

function setupForm() {
  const form = document.querySelector('form');
  const submitBtn = document.querySelector('[type="submit"]');
  const formFields = form.querySelectorAll('input, textarea');

  // Убить стандартное поведение отправки формы
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    console.log('Форма НЕ отправляется стандартно');
    // Здесь отправляем через AJAX
  });

  // Остановить всплытие клика на кнопке отправки
  submitBtn.addEventListener('click', (e) => {
    if (!validateForm()) {
      e.stopPropagation();
      console.log('Форма не валидна, отправка отменена');
    }
  });

  // Логирование при клике на любое поле
  form.addEventListener('click', (e) => {
    console.log('Клик внутри формы');
  });
}

function validateForm() {
  return true; // Простая проверка
}

setupForm();

Когда использовать

stopPropagation():

  • Модальные окна (остановить клик на overlay)
  • Nested компоненты (меню внутри меню)
  • Drag and drop
  • Custom UI компоненты

preventDefault():

  • Форма (вместо стандартной отправки)
  • Ссылка (вместо навигации)
  • Context menu
  • Стандартные браузерные действия

Делегирование (без остановки):

  • Списки элементов
  • Большое количество элементов
  • Динамически добавляемые элементы

Правильное управление всплытием событий - это ключ к разработке корректных и производительных интерактивных компонентов.

Как остановить Bubbling после click? | PrepBro