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
body
div
Existem várias formas de propagação de eventos:
: o evento se propaga para cima na árvore DOM, dos nós filhos para os nós pais.Eventos de bolha (bubbling)
: 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 captura (capturing)
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
div
body
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()
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()
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()
true
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: