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