JavaScript Event Handlers - Sådan håndteres begivenheder i JS

Hvad er begivenheder?

Begivenheder er handlinger, der sker, når en bruger interagerer med siden - som at klikke på et element, skrive i et felt eller indlæse en side.

Browseren underretter systemet om, at der er sket noget, og at det skal håndteres. Det håndteres ved at registrere en funktion, kaldet en event handler, der lytter til en bestemt type begivenhed.

Hvad betyder det at "håndtere en begivenhed"?

For at udtrykke det i enkle vendinger, overvej dette - lad os antage, at du er interesseret i at deltage i webudviklingsmøderbegivenheder i dit lokale samfund.

For at gøre dette tilmelder du dig et lokalt møde kaldet "Kvinder der koder" og abonnerer på underretninger. På denne måde bliver du advaret når som helst et nyt møde er planlagt. Det er håndtering af begivenheder!

"Begivenheden" her er et nyt JS-møde. Når der offentliggøres et nyt møde, fanger hjemmesiden meetup.com denne ændring og derved "håndterer" denne begivenhed. Det giver dig derefter besked og tager således en "handling" på begivenheden.

I en browser håndteres begivenheder på samme måde. Browseren registrerer en ændring og advarer en funktion (begivenhedshåndterer), der lytter til en bestemt begivenhed. Disse funktioner udfører derefter handlingerne som ønsket.

Lad os se på et eksempel på en clickbegivenhedshåndterer:

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

Hvad er de forskellige typer begivenheder?

En begivenhed kan udløses, når som helst en bruger interagerer med siden. Disse begivenheder kan være en bruger, der ruller gennem siden, klikker på et element eller indlæser en side.

Her er nogle almindelige begivenheder - onclickdblclickmousedownmouseupmousemovekeydownkeyuptouchmovetouchstarttouchendonloadonfocusonbluronerror onscroll

Forskellige faser af begivenheder - capture, target, bubble

Når en begivenhed bevæger sig gennem DOM - hvad enten den bobler op eller siver ned - kaldes den begivenhedsformering. Begivenheden udbredes gennem DOM-træet.

Begivenheder sker i to faser: den boblende fase og indfangningsfasen.

I opsamlingsfasen, også kaldet sildefasen, "sildrer begivenheden" ned til det element, der forårsagede begivenheden.

Det starter fra rodniveauelementet og -handleren og udbreder sig derefter ned til elementet. Optagelsesfasen er afsluttet, når begivenheden når target.

I boblefasen "bobles" begivenheden op til DOM-træet. Den fanges først og håndteres af den inderste handler (den, der er tættest på det element, hvor begivenheden fandt sted). Derefter bobler den op (eller formerer sig) til de højere niveauer af DOM-træet, længere op til sine forældre og derefter endelig til dens rod.

Det er et trick, der hjælper dig med at huske dette:

trickle down, bubble up 

Her er en infografik fra quirksmode, der forklarer dette meget godt:

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

En ting at bemærke er, at uanset om du registrerer en begivenhedshåndterer i begge faser, sker begge faser ALLTID. Alle begivenheder boble som standard.

Du kan registrere begivenhedshåndterere til enten fase, boblende eller optagelse ved hjælp af funktionen addEventListener(type, listener, useCapture). Hvis useCaptureer indstillet til false, er begivenhedshåndtereren i den boblende fase. Ellers er det i fangstfasen.

Rækkefølgen af ​​begivenhedens faser afhænger af browseren.

For at kontrollere, hvilken browser der udmønter sig først, kan du prøve følgende kode i 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); 

I Firefox, Safari og Chrome er output følgende:

Begivenheder i fangstfasen affyres først

Sådan lytter du til en begivenhed

Der er to måder at lytte til en begivenhed på:

  1. addEventListener
  2. inline begivenheder, såsom onclick
//addEventListener document.getElementByTag('a').addEventListener('click', onClickHandler); //inline using onclick Click me 

Hvilket er bedre - en indbygget begivenhed eller addEventListener?

  1. addEventListener giver dig mulighed for at registrere ubegrænset begivenhedshåndtering.
  2. removeEventListener kan også bruges til at fjerne begivenhedshåndterere
  3. Den useCaptureflag kan bruges til at indikere, om en begivenhed skal håndteres i capture fase eller bundtet fase.

Kodeeksempler og live-action

Du kan prøve disse begivenheder i JSFiddle for at lege med dem.

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

Begivenhedsfaser er capture (DOM -> target), bubble (target-> DOM) og target.

Man kan lytte til begivenheder ved hjælp af addEventListenereller integrerede metoder som f.eks 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. 

Yderligere læsning

//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_Attributter

For at holde øje med flere korte tutorials som denne, tilmeld dig mit nyhedsbrev eller følg mig på Twitter