Eventos

Os eventos em JavaScript são fundamentais para criar interatividade nas páginas web.

Eventos são ações ou ocorrências detetadas pelo programa, geralmente iniciadas pelo utilizador. Exemplos incluem cliques, pressão de teclas, carregamento de página, etc.

Lista de eventos mais comuns

EventoDescrição
onchangeUm elemento de HTML mudou
onclickO utilizador clicou num elemento de HTML
ondblclickO utilizador fez duplo clique num elemento de HTML
onmouseoverO utilizador move o rato sobre um elemento de HTML
onmouseoutO utilizador sai com o rato de um elemento de HTML
onkeydownO utilizador carrega numa tecla para baixo
onkeyupO utilizador liberta uma tecla
onloadO browser terminou de carregar uma página
onfocusQuando o rato se posiciona num elemento(ex: <input>)
onsubmitQuando o utilizador submete um <FORM>

Tratadores de eventos (event handlers)

Um tratador de evento (event handler) é uma função que executa no caso de ocorrer um determinado evento.

Para que uma função execute no caso de um evento ocorrer, temos de registar essa função para esse evento.

Existem 3 formas de registar uma função tratadora de um evento:

Como um atributo de HTML

Podemos registar uma função tratadora de evento num elemento de HTML num atributo chamado on<evento> em que <evento> é um dos muitos eventos existentes:

<input type="button" value="Click me" onclick="mostra()">

No exemplo acima, a função mostra() é uma função tratadora de evento (event handler) que irá correr quando o evento click do botão ocorrer.

Como uma propriedade do DOM

Podemos registar uma função tratadora de evento numa propriedade do DOM chamada on<evento> em que <evento> é um dos muitos eventos existentes:

let btn = document.getElementById('btn1'); 

btn1.onclick = function(){ 
   alert("Button clicked!"); 
} 

Usando addEventListener

A função addEventListener permite registar uma função tratadora de evento a um elemento do DOM. Uma das vantagens deste método é que nos permite registar múltiplas funções tratadoras de evento a um mesmo elemento.

A sintaxe desta função é a seguinte:

element.addEventListener(event, handler[, options]);

event: string com o nome do evento
handler: função tratadora do evento

options:
once: se true, a função é removida depois do evento disparar
capture: true/false. A fase em que se pretende capturar o evento

Exemplo 1:

<body> 
    <button id='btn1'>Gravar</button> 
    <script> 
            function mostra(){ 
                alert("Button clicked"); 
            } 
             
            let btn1 = document.getElementById('btn1'); 
            btn1.addEventListener('click', mostra); 
        </script> 
</body> 

Exemplo 2:

<body> 
    <button id='btn1'>Gravar</button> 
    <script> 
            function mostra(){ 
                alert("Button clicked"); 
            } 
 
            function mostra2(){ 
                alert("Mouse out"); 
            }             
             
            let btn1 = document.getElementById('btn1'); 
            btn1.addEventListener('click', mostra); 
            btn1.addEventListener('click', mostra2) 
        </script> 
</body> 

Neste exemplo, atribuímos 2 funções tratadoras de eventos para o mesmo evento do mesmo elemento.

Para alguns eventos as funções tratadoras de eventos só funcionam se forem adicionadas com addEventListener(). É o caso, por exemplo, do evento transitioned (animação de CSS terminada).

Remoção da função tratadora de evento

Podemos remover uma função tratadora de evento adicionada com addEventListener(), usando a função removeEventListener():

function handler() { 
alert( 'Thanks!' ); 
} 
input.addEventListener("click", handler); 
// .... 
input.removeEventListener("click", handler); 

Objeto que trata um evento: eventHandler

Usando a função addEventListener, podemos registar um objeto para tratar um determinado evento.

Esse objeto deve ter um método de nome handleEvent(), que será chamado de cada vez que o evento ocorrer:

<body> 
<div id='div1' style="padding:50px; background: 
yellow"></div> 
<script> 
//objeto que irá tratar o evento 
let objListener = { 
handleEvent(e){ 
alert(e.type); 
} 
} 
var div1 = document.getElementById('div1'); 
div1.addEventListener('click', objListener); 
</script> 
</body>

O objeto event

O objeto event permite-nos saber informação mais especifica sobre determinado evento que tenha sido disparado. Podemos obter o elemento que despoletou o evento, obter coordenadas do rato em alguns eventos, o tipo de evento, etc..

Propriedades do objeto event

Estas são as propriedades mais importantes do objeto event:


event.type
O tipo do evento. Por exemplo, ‘click’.

event.currentTarget
O elemento que tratou o evento

event.target
O elemento que disparou o evento

event.clientX, event.clientY
Coordenadas do rato no elemento que despoletou o evento.

Exemplo 1:

 <body>
<div id='div1' style="padding:50px; background: yellow"></div> 
    <script> 
        function process(){ 
            alert(event.clientX + ', ' + event.clientY); 
        } 
 
        var div1 = document.getElementById('div1'); 
        div1.addEventListener('click', process); 
    </script> 
</body>

Neste exemplo vemos as coordenadas do rato na DIV, de cada vez que há um clique sobre ela.

Exemplo 2:

<body> 
    <div id='div1' style="padding:50px; background: 
yellow"></div> 
    <script> 
        function process(){ 
            console.log('Tipo: ' + event.type); 
            console.log('currentTarget: ' + 
event.currentTarget); 
            console.log('target: ' + event.target); 
        } 
 
        var div1 = document.getElementById('div1'); 
        div1.addEventListener('click', process); 
    </script> 
</body> 

Neste exemplo, mostramos as diferentes propriedades do evento.

Propagação de um evento

Básicamente, a propagação de um evento significa que quando um evento é gerado num elemento ele propaga-se por todos os elementos ancestrais deste.

Considere-se a seguinte página de HTML:

<body> 
   <div> 
      <p> 
         <a href="google.com">Google</a> 
      </p> 
   </div> 
</body> 

Um clique no elemento A irá gerar um evento click nesse elemento. No entanto, não fica por aqui : esse evento click irá propagar-se pelo elemento P, pelo elemento DIV, pelo próprio documento, até ao objeto window, podendo ser capturado por qualquer destes elementos e objetos.

Chama-se a isto bubbling !

O evento propaga-se desde o elemento que gerou o evento passando por todos os elementos ancestrais deste.

Fases de um evento

Um evento passa por 3 fases:

  • Fase de captura
  • Fase de target
  • Fase de bubble

Fase de captura

Na fase de captura, o evento propaga-se desde o objeto window, passando por todos os objetos e elementos intermédios, até chegar ao elemento que gerou o evento, que é o elemento target.

Nesta fase o evento só pode ser tratado pela função addEventListener(), tendo o 3º parâmetro definido a true.

Todos os outros métodos de tratar eventos não podem capturar eventos nesta fase.

Fase de target

A fase de captura é quando o evento atinge o elemento que o gerou. Todos os métodos de tratamento de eventos podem tratar o evento nesta fase.

Fase de bubble

O evento propaga-se por todos os elementos ancestrais do elemento que gerou o evento.

Todos os métodos de tratamento de eventos podem tratar o evento nesta fase.

NOTA: eventos como focus, blur, load não se propagam nesta fase.

Interromper a propagação

Podemos interromper a propagação de um evento durante as fases de captura e/ou de bubbling através do método stopPropagation() do objeto event:

<body> 
   <div> 
      <p> 
         <a href="#">Google</a> 
      </p> 
   </div> 
   <script> 
      function mostra(){ 
         alert(this.tagName + ' clicked'); 
         //interrompe a propagação para outros elementos 
         event.stopPropagation(); 
      } 
      let a = document.getElementsByTagName('a')[0]; 
      let p = document.getElementsByTagName('P')[0]; 
      let div = document.getElementsByTagName('div')[0]; 
      a.addEventListener('click', mostra); 
      p.addEventListener('click', mostra); 
      div.addEventListener('click', mostra); 
      document.addEventListener('click', mostra); 
      window.addEventListener('click', mostra); 
   </script> 
</body>

NOTA: a interrupção da propagação de um evento deve ser evitada e só deve ser posta em prática em situações muito especiais.

this e event.target

this refere-se ao elemento corrente para o qual o evento se propagou.

event.target refere-se ao elemento no qual o evento foi originado.

Exemplo:

Neste exemplo podemos ver as 3 fases por que passa o evento click. Na fase de captura, o evento é tratado pela função addEventListener() com o 3º parâmetro a true.

Nas restantes duas fases (target e bubbling) o evento é tratado pelos métodos normais.

<body> 
   <div> 
      <p> 
         <a href="#">Google</a> 
      </p> 
   </div> 
   <script> 
      function mostra1(){ 
         alert('A clicked'); 
      } 
      function mostra2(){ 
         alert('P clicked'); 
      } 
      function mostra3(){ 
          alert('DIV clicked'); 
      } 
      function mostra4(){ 
          alert('DOCUMENT clicked'); 
      } 
      function mostra5(){ 
          alert('WINDOW clicked'); 
      } 
      let a = document.getElementsByTagName('a')[0]; 
      let p = document.getElementsByTagName('P')[0]; 
      let div = document.getElementsByTagName('div')[0]; 
      a.addEventListener('click', mostra1, true); 
      p.addEventListener('click', mostra2, true); 
      div.addEventListener('click', mostra3, true); 
      document.addEventListener('click', mostra4, true); 
      window.addEventListener('click', mostra5, true); 
 
      a.addEventListener('click', mostra1); 
      p.addEventListener('click', mostra2); 
      div.addEventListener('click', mostra3); 
      document.addEventListener('click', mostra4); 
      window.addEventListener('click', mostra5); 
 
    </script> 
</body>