JavaScript EventTarget — addEventListener для будь-чого


EventTarget — базовий клас усього, що вміє приймати події: елементів, window, document, XMLHttpRequest, навіть власних класів.

автор: NagarD

Загальний опис

Саме звідси беруться addEventListener(), removeEventListener() і dispatchEvent() — вони не належать елементам, вони успадковані.

І це відкриває непомічену можливість: свій клас теж може бути джерелом подій. Досить успадкуватись від EventTarget — і з ним працюватимуть ті самі addEventListener і CustomEvent, що й з кнопкою. Не треба вигадувати власну систему підписок.

Власні дані передаються через поле detail у CustomEvent.

Важливий сучасний прийом — опція { signal }: обробник знімається сам, коли спрацює AbortController. Це найнадійніший спосіб прибрати за собою й не залишити витік.

автор: NagarD

Порада

addEventListener(..., { once: true }) знімає обробник після першого спрацювання — не треба тримати посилання на функцію, щоб потім її зняти.

автор: NagarD

Синтаксис

target.addEventListener("click", handler);

методи

Метод Опис
addEventListener Додає обробник події.
removeEventListener Знімає обробник події.
dispatchEvent Штучно запускає подію на цілі.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
EventTarget 1+ 1+ 1+ 7+ 12+ 9+
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
EventTarget yes yes yes yes

Приклади

+ запропонувати свій приклад у пісочниці

Власний клас, що надсилає події, і зняття обробників сигналом.

HTML

<button id="demo-button">Кнопка</button>

JS

function onClick() {
    console.log('клік');
}

function onResize() {
    console.log('resize');
}

const button = document.getElementById('demo-button');

class Store extends EventTarget {
    constructor() {
        super();
        this.items = [];
    }

    add(item) {
        this.items.push(item);
        // своя подія — з даними в detail
        this.dispatchEvent(new CustomEvent('added', { detail: item }));
    }
}

const store = new Store();

store.addEventListener('added', event => {
    console.log('Додано:', event.detail);
});

store.add({ id: 1, name: 'CSS' });

// зняти всі обробники одним рухом
const controller = new AbortController();

button.addEventListener('click', onClick, { signal: controller.signal });
window.addEventListener('resize', onResize, { signal: controller.signal });

controller.abort(); // знято обидва
автор: NagarD

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід