O que são eventos?

Eventos são ações que acontecem quando um usuário interage com a página – como clicar em um elemento, digitar em um campo ou carregar uma página.

O navegador notifica o sistema de que algo aconteceu e que precisa ser tratado. Ele é tratado registrando uma função, chamada de event handler, que escuta um tipo específico de evento.

O que significa “tratar um evento”?

Para colocar em termos simples, considere o seguinte – vamos supor que você esteja interessado em participar de eventos Meetup de Desenvolvimento Web em sua comunidade local.

Para fazer isso, você se inscreve em um encontro local chamado “Mulheres que codificam” e se inscreve para receber notificações. Dessa forma, sempre que um novo encontro for agendado, você será alertado. Isso é manipulação de eventos!

O “evento” aqui é um novo encontro JS. Quando um novo encontro é postado, o site meetup.com capta essa mudança, “tratando” desse evento. Em seguida, ele o notifica, realizando uma “ação” no evento.

Em um navegador, os eventos são tratados de forma semelhante. O navegador detecta uma mudança e alerta uma função (manipulador de eventos) que está ouvindo um determinado evento. Essas funções então executam as ações desejadas.

Vejamos um exemplo de click manipulador de eventos:

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

Quais são os diferentes tipos de eventos?

Um evento pode ser acionado a qualquer momento em que um usuário interage com a página. Esses eventos podem ser um usuário rolar pela página, clicar em um item ou carregar uma página.

Aqui estão alguns eventos comuns – onclick dblclick mousedown mouseup mousemove keydown keyup touchmove touchstart touchend onload onfocus onblur onerror onscroll

Diferentes fases de eventos – captura, alvo, bolha

Quando um evento se move através do DOM – borbulhando ou descendo – é chamado de propagação de evento. O evento se propaga pela árvore DOM.

Os eventos acontecem em duas fases: a fase de borbulhamento e a fase de captura.

Na fase de captura, também chamada de fase de gotejamento, o evento “desce” até o elemento que causou o evento.

Ele começa a partir do elemento e manipulador de nível raiz e, em seguida, se propaga para o elemento. A fase de captura é concluída quando o evento atinge o target.

Na fase de bolha, o evento é “borbulhado” na árvore DOM. Ele é primeiro capturado e manipulado pelo manipulador interno (aquele que está mais próximo do elemento no qual o evento ocorreu). Em seguida, ele borbulha (ou se propaga) para os níveis mais altos da árvore DOM, mais para cima até seus pais e, finalmente, para sua raiz.

É um truque para ajudá-lo a se lembrar disso:

trickle down, bubble up

Aqui está um infográfico de modo peculiar isso explica muito bem:

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

Uma coisa a notar é que, se você registrar um manipulador de eventos em qualquer fase, ambas as fases SEMPRE acontecem. Todos os eventos borbulham por padrão.

Você pode registrar manipuladores de eventos para qualquer fase, bolha ou captura, usando a função addEventListener(type, listener, useCapture). E se useCapture está configurado para false, o manipulador de eventos está na fase de bolhas. Caso contrário, está em fase de captura.

A ordem das fases do evento depende do navegador.

Para verificar qual navegador deve ser capturado primeiro, você pode tentar o seguinte código em JSfiddle:

<div id="child-one">    <h1>      Child One    </h1>  </div>
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); 

No Firefox, Safari e Chrome, o resultado é o seguinte:
Os eventos na fase de captura são disparados primeiro

Como ouvir um evento

Existem duas maneiras de ouvir um evento:

  1. addEventListener
  2. eventos inline, como onclick
//addEventListenerdocument.getElementByTag('a').addEventListener('click', onClickHandler);//inline using onclick<a href="#" onclick="onClickHandler">Click me</a>

O que é melhor – um evento inline ou addEventListener?

  1. addEventListener oferece a capacidade de registrar manipuladores de eventos ilimitados.
  2. removeEventListener também pode ser usado para remover manipuladores de eventos
  3. o useCapture O sinalizador pode ser usado para indicar se um evento precisa ser tratado na fase de captura ou na fase de pacote.

Exemplos de código e ação ao vivo

Você pode experimentar esses eventos no JSFiddle para brincar com eles.

<div id="wrapper-div">  <div id="child-one">    <h1>      Child One    </h1>  </div>  <div id="child-two" onclick="childTwoHandler">    <h1>      Child Two    </h1>  </div></div>
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

As fases do evento são captura (DOM -> alvo), bolha (alvo-> DOM) e alvo.
Os eventos podem ser ouvidos usando addEventListener ou métodos inline, como 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 <script> elements.    addEventListener can take a third argument which can stop the event propagation.

Leitura futura

https://www.quirksmode.org/js/events_order.html
https://jsfiddle.net/r2bc6axg/
https://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick
https://www.w3.org/wiki/HTML/Attributes/_Global#Event-handler_Attributes

Para acompanhar mais tutoriais curtos como este, inscreva-se no meu boletim informativo ou Siga me no twitter