Обробники подій JavaScript - Як обробляти події в JS

Що таке події?

Події - це дії, які відбуваються під час взаємодії користувача зі сторінкою - наприклад, клацання елемента, введення тексту в поле чи завантаження сторінки.

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

Що означає "обробляти подію"?

Якщо сказати простими словами, розгляньте це - припустимо, ви зацікавлені відвідати зустрічі веб-розробки у вашій місцевій громаді.

Для цього ви підписуєтесь на місцеву зустріч під назвою "Жінки, які кодують" і підписуєтеся на сповіщення. Таким чином, щоразу, коли запланована нова зустріч, ви отримуватимете сповіщення. Це обробка подій!

"Подією" тут є нова зустріч JS. Коли розміщується нова зустріч, веб-сайт meetup.com вловлює цю зміну, тим самим "обробляючи" цю подію. Потім воно сповіщає вас, тим самим вживаючи "дії" щодо події.

У браузері події обробляються однаково. Браузер виявляє зміни та попереджає функцію (обробник подій), яка прослуховує певну подію. Потім ці функції виконують дії за бажанням.

Давайте розглянемо приклад clickобробника подій:

 Press 1 Press 2 Press 3 const buttonContainer = document.querySelector('.buttons'); console.log('buttonContainer', buttonContainer); buttonContainer.addEventListener('click', event => { console.log(event.target.value) }) 

Які різні типи подій?

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

Ось кілька загальних подій - onclickdblclickmousedownmouseupmousemovekeydownkeyuptouchmovetouchstarttouchendonloadonfocusonbluronerror onscroll

Різні фази подій - захоплення, ціль, міхур

Коли подія рухається через DOM - будь то бульбашка вгору чи стікає вниз - це називається поширенням події. Подія поширюється через дерево DOM.

Події відбуваються у дві фази: фаза барботування та фаза захоплення.

У фазі захоплення, яку також називають фазою стікання, подія "стікає" до елемента, що спричинив подію.

Він починається з елемента кореневого рівня та обробника, а потім поширюється до елемента. Фаза захоплення завершується, коли подія досягає target.

У фазі міхура подія "пузириться" до дерева DOM. Спочатку його фіксує і обробляє внутрішній обробник (той, який знаходиться найближче до елемента, на якому відбулася подія). Потім воно пузириться (або поширюється) на вищі рівні дерева DOM, далі до своїх батьків, а потім, нарешті, до свого кореня.

Її фокус допоможе вам запам’ятати це:

trickle down, bubble up 

Ось інфографіка від quirksmode, яка дуже добре пояснює це:

 / \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | ----------------------------------- | | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | ----------------------------------- 

Зазначимо одне, що, незалежно від того, зареєструєте ви обробник події в будь-якій фазі, обидві фази ЗАВЖДИ відбуваються. Усі події за замовчуванням спливають.

Ви можете зареєструвати обробники подій для будь-якої фази, бульбашки або захоплення, використовуючи функцію addEventListener(type, listener, useCapture). Якщо useCaptureвстановлено значення false, обробник подій перебуває у фазі спливання. В іншому випадку це на фазі захоплення.

Порядок фаз події залежить від браузера.

Щоб перевірити, які відзнаки браузера захоплюють першими, ви можете спробувати такий код у JSfiddle:

Child One

const childOne = document.getElementById("child-one"); const childOneHandler = () => { console.log('Captured on child one') } const childOneHandlerCatch = () => { console.log('Captured on child one in capture phase') } childOne.addEventListener("click", childOneHandler); childOne.addEventListener("click", childOneHandlerCatch, true); 

У Firefox, Safari та Chrome результат виходить:

Події у фазі захоплення запускаються першими

Як прослухати подію

Існує два способи прослуховування події:

  1. addEventListener
  2. вбудовані події, такі як onclick
//addEventListener document.getElementByTag('a').addEventListener('click', onClickHandler); //inline using onclick Click me 

Що краще - вбудована подія чи addEventListener?

  1. addEventListener надає можливість реєструвати необмежену кількість обробників подій.
  2. removeEventListener також може використовуватися для видалення обробників подій
  3. useCaptureПрапор може бути використаний для вказівки , чи потрібно цю подію буде оброблятися в фазі захоплення або комплектної фазі.

Приклади коду та живі дії

Ви можете спробувати ці події в JSFiddle, щоб пограти з ними.

Child One

Child Two

const wrapperDiv = document.getElementById("wrapper-div"); const childOne = document.getElementById("child-one"); const childTwo = document.getElementById("child-two"); const childOneHandler = () => { console.log('Captured on child one') } const childTwoHandler = () => { console.log('Captured on child two') } const wrapperDivHandler = () => { console.log('Captured on wrapper div') } const childOneHandlerCatch = () => { console.log('Captured on child one in capture phase') } const childTwoHandlerCatch = () => { console.log('Captured on child two in capture phase') } const wrapperDivHandlerCatch = () => { console.log('Captured on wrapper div in capture phase') } childOne.addEventListener("click", childOneHandler); childTwo.addEventListener("click", childTwoHandler); wrapperDiv.addEventListener("click", wrapperDivHandler); childOne.addEventListener("click", childOneHandlerCatch, true); childTwo.addEventListener("click", childTwoHandlerCatch, true); wrapperDiv.addEventListener("click", wrapperDivHandlerCatch, true); 

TL; DR

Фази події - це захоплення (DOM -> ціль), міхур (ціль-> DOM) і ціль.

Події можна слухати за допомогою addEventListenerвбудованих методів, таких як onclick.

 addEventListener can add multiple events, whereas with onclick this cannot be done. onclick can be added as an HTML attribute, whereas an addEventListener can only be added within  elements. addEventListener can take a third argument which can stop the event propagation. 

Далі читання

//www.quirksmode.org/js/events_order.html

//jsfiddle.net/r2bc6axg/

//stackoverflow.com/questions/6348494/addeventlistener-vs-onclick

//www.w3.org/wiki/HTML/Attributes/_Global#Event-handler_Attributes

Щоб не відставати від таких коротких навчальних посібників, як цей, підпишіться на мій бюлетень або слідкуйте за мною у Twitter