Пояснення спливання подій (event bubbling) і як його можна запобігти в javascript?

Додано (оновлено): Jul 7, 2024, 5:48 PM
Пояснення спливання подій (event bubbling) і як його можна запобігти в javascript?

JavaScript є потужною мовою програмування, яка дозволяє створювати інтерактивні веб-сторінки. Однією з важливих концепцій в JavaScript є спливання подій (event bubbling). У цій статті ми детально розглянемо, що таке спливання подій, як воно працює, та які існують способи його запобігання. 🔍

Що таке спливання подій? 🌊

Спливання подій - це механізм, який визначає, як події поширюються через DOM (Document Object Model) після їх виникнення. Коли подія виникає на певному елементі, вона спершу обробляється цим елементом, а потім "спливає" до його батьківських елементів, і так далі до самого кореня документа.

Приклад спливання подій 📝

Уявімо наступну HTML-структуру:


При натисканні на кнопку button, подія спочатку виникає на кнопці, а потім спливає до div, а далі до body та html елементів. Це називається спливанням події.

Як працює спливання подій? 🔄

Коли подія виникає, вона проходить через три фази:

  1. Фаза захоплення (Capturing Phase): Подія спускається від кореня документа до цільового елемента.
  2. Цільова фаза (Target Phase): Подія досягає цільового елемента.
  3. Фаза спливання (Bubbling Phase): Подія спливає від цільового елемента до кореня документа.

Для наочності, розглянемо наступний приклад:


document.getElementById('parent').addEventListener('click', function() {
    console.log('Parent clicked!');
});

document.getElementById('child').addEventListener('click', function() {
    console.log('Child clicked!');
});

Якщо натиснути на кнопку button, консоль відобразить наступне:


Child clicked!
Parent clicked!

Це демонструє, що подія спочатку обробляється цільовим елементом (кнопкою), а потім спливає до його батьківського елемента (div).

Запобігання спливанню подій 🚫

Іноді спливання подій небажане, і ми хочемо обробити подію лише на цільовому елементі, не дозволяючи їй спливати далі. Існує кілька способів досягти цього:

Метод stopPropagation() 🛑

Метод stopPropagation() запобігає подальшому поширенню події. Додамо його до нашого попереднього прикладу:


document.getElementById('child').addEventListener('click', function(event) {
    console.log('Child clicked!');
    event.stopPropagation();
});

document.getElementById('parent').addEventListener('click', function() {
    console.log('Parent clicked!');
});

Тепер, якщо натиснути на кнопку button, консоль відобразить лише:


Child clicked!

Це відбувається тому, що метод stopPropagation() зупиняє спливання події після її обробки на цільовому елементі.

Метод stopImmediatePropagation()

Метод stopImmediatePropagation() не лише зупиняє спливання події, але й запобігає виклику інших обробників події на тому ж елементі:


document.getElementById('child').addEventListener('click', function(event) {
    console.log('First handler');
    event.stopImmediatePropagation();
});

document.getElementById('child').addEventListener('click', function() {
    console.log('Second handler');
});

При натисканні на кнопку button консоль відобразить:


First handler

Другий обробник події не буде викликаний через stopImmediatePropagation().

Роздільне оброблення фаз спливання та захоплення 🌐

В JavaScript ми можемо вказати, на якій фазі обробляти подію: на фазі захоплення або на фазі спливання. За замовчуванням події обробляються на фазі спливання, але можна змінити це, передавши третій параметр true при додаванні обробника події:


document.getElementById('parent').addEventListener('click', function() {
    console.log('Parent clicked during capturing!');
}, true);

document.getElementById('child').addEventListener('click', function() {
    console.log('Child clicked!');
});

В такому випадку подія буде оброблена під час фази захоплення, а не спливання.

Практичні приклади використання 📚

Розглянемо декілька практичних прикладів, коли може знадобитися запобігання спливанню подій.

Меню та випадаючі списки 📋

У випадку створення меню або випадаючих списків, ми можемо використовувати stopPropagation(), щоб запобігти закриттю меню при натисканні на елементи всередині нього:


document.querySelector('.menu').addEventListener('click', function(event) {
    event.stopPropagation();
});

document.addEventListener('click', function() {
    document.querySelector('.menu').style.display = 'none';
});

Цей код запобігає закриттю меню при натисканні на його елементи, дозволяючи користувачу вибирати опції без закриття меню.

Форми та валідація 📄

При валідації форм можна використовувати stopPropagation(), щоб зупинити подальше оброблення подій, якщо виявлено помилки:


document.querySelector('form').addEventListener('submit', function(event) {
    if (!formIsValid()) {
        event.stopPropagation();
        event.preventDefault();
    }
});

Цей підхід дозволяє зупинити подальшу обробку подій у разі невдалої валідації форми.

Таблиця порівняння методів запобігання спливанню подій 📊

Метод Опис Приклад
stopPropagation() Зупиняє спливання події до батьківських елементів

event.stopPropagation();
        
stopImmediatePropagation() Зупиняє спливання події і інші обробники на тому ж елементі

event.stopImmediatePropagation();
        

Висновок 🏁

Спливання подій є важливою частиною механізму подій у JavaScript, яка дозволяє подіям поширюватися від цільового елемента до кореня документа. Це може бути дуже корисним, але іноді потрібно зупинити спливання подій для досягнення бажаного поведінки. Використання методів stopPropagation() та stopImmediatePropagation() дозволяє точно контролювати, як обробляються події на вашій веб-сторінці.

Розуміння цих концепцій допоможе вам краще керувати подіями та створювати більш інтуїтивні і гнучкі інтерфейси для користувачів. 💡


Поділіться з друзями: