Propagação de Eventos - JavaScript

Quando clicamos em um elemento na página, um evento de clique é gerado e esse evento pode se propagar de elemento para elemento. Por exemplo, se clicarmos em um bloco div, também estamos clicando no elemento body que contém esse div. Isso é chamado de propagação de evento.

Existem várias formas de propagação de eventos:

  • Eventos de bolha (bubbling): o evento se propaga para cima na árvore DOM, dos nós filhos para os nós pais.

  • Eventos de captura (capturing): o evento se propaga para baixo na árvore DOM, dos nós pais para os nós filhos, até alcançar o elemento onde o evento foi gerado.

Eventos de Bolha

Consideremos eventos de bolha(bubbling), que se propagam para cima na árvore DOM. Suponha que temos a seguinte página web:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
    <style>
    #blueRect {
        width:100px;
        height:100px;
        background-color:blue;
    }
    #redRect {
        position: relative;
        top: 25px;
        left: 25px;
        width:50px;
        height:50px;
        background-color:red;
    }
    </style>
</head>
<body>
    <div id="blueRect">
        <div id="redRect"></div>
    </div>
    <script>
    const redRect = document.getElementById("redRect");
    redRect.addEventListener("click", () => console.log("Evento no redRect"));
        
    const blueRect = document.getElementById("blueRect");
    blueRect.addEventListener("click", () => console.log("Evento no blueRect"));
        
    document.body.addEventListener("click", () => console.log("Evento no body"));
    </script>
</body>
</html>

Se clicarmos no div interno (vermelho), o evento irá se propagar para o div pai e, em seguida, para o elemento body:

Evento de bolha em JavaScript

Controle dos Eventos de Bolha

É importante notar que esse comportamento nem sempre é desejado. Nesse caso, podemos interromper a propagação do evento usando o método stopPropagation() do objeto Event:

const redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(e) {
    console.log("Evento no redRect");
    e.stopPropagation();
});

Como resultado, o evento será tratado apenas pelo manipulador do redRect.

No entanto, stopPropagation() tem uma limitação: ele impede a execução de outros manipuladores de eventos no mesmo elemento. Para evitar isso, podemos usar stopImmediatePropagation():

const redRect = document.getElementById("redRect");
function handler1(e) {
    console.log("handler1: Evento no redRect");
    e.stopImmediatePropagation();
}
function handler2(e) {
    console.log("handler2: Evento no redRect");
}
redRect.addEventListener("click", handler1);
redRect.addEventListener("click", handler2);

Eventos de Captura

Os eventos também podem ser de captura(capturing). Para utilizá-los, passamos um valor lógico true como terceiro parâmetro opcional no método addEventListener(). O valor true indica que o evento será de captura. Por padrão, todos os eventos são de bolha.

Modificando o código JavaScript da mesma página, teremos:

const redRect = document.getElementById("redRect");
  redRect.addEventListener("click", function() {
      console.log("Evento no redRect");
  }, true);
   
  const blueRect = document.getElementById("blueRect");
  blueRect.addEventListener("click", function() {
      console.log("Evento no blueRect");
  }, true);
   
  document.body.addEventListener("click", function() {
      console.log("Evento no body");
  }, true);
  

Agora, os eventos se propagarão na ordem inversa:

Evento de bolha em JavaScript
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com