Propagação de Eventos no JavaScript: Bubbling, stopPropagation e preventDefault

No desenvolvimento web, compreneder como os eventos se comportam na árvore DOM é fundamental. A propagação de eventos, especificamente o event bubbling (ou borbulhamento de eventos), ocorre quando um evento disparado em um elemento filho é subsequentemente propagado para seus ancestrais. Se um elemento não interceptar ou cancelar a propagação, o evento "sobe" pela hierarquia até atingir o objeto document (ou window em alguns contextos).

Demonstração Prática do Bubbling

Considere a seguinte estrutura HTML com três níveis de aninhamento. Cada elemento possui um manipulador para o evento de clique:


<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Hierarquia de Eventos</title>
    <style>
        .wrapper-external { padding: 30px; border: 2px dashed blue; }
        .wrapper-internal { padding: 20px; border: 2px dashed green; }
    </style>
</head>
<body>
    <div class="wrapper-external" onclick="console.log('Nível externo acionado');">
        <div class="wrapper-internal" onclick="console.log('Nível intermediário acionado');">
            <a id="target-link" href="https://developer.mozilla.org" onclick="console.log('Nível interno acionado');">Executar Ação</a>
        </div>
    </div>
</body>
</html>

Ao interagir com o link "Executar Ação", a sequência de execução no console será:

  1. Nível interno acionado
  2. Nível intermediário acionado
  3. Nível externo acionado
  4. Redriecionamento para a URL especificada no href.

Isso ilustra perfeitamente o bubbling: a interação ocorreu no elemento mais profundo (target-link), mas os elementos pais também reagiram ao mesmo evento.

Interrompendo a Propagação (stopPropagation)

Para evitar que o evento continue subindo na árvore DOM e acionando os listeners dos elementos pais, utilizamos o método event.stopPropagation(). Isso isola a execução apenas ao elemento que originou o evento.

document.addEventListener('DOMContentLoaded', function() {
    var linkElement = document.querySelector('#target-link');
    
    linkElement.addEventListener('click', function(e) {
        // Impede que o evento chegue aos divs pais
        e.stopPropagation();
        console.log('Ação interna processada sem propagar.');
    });
});

Com essa implementação, ao clicar no link, apenas a mensagem do nível interno será exibida no console, seguida pelo redirecionamento padrão da página.

Cancelando o Comportamento Padrão (preventDefault)

Em alguns cenários, o objetivo não é bloquear a propagação, mas sim anular a ação nativa do elemento, como o envio de um formulário ou o redirecionamento de um link. Para isso, aplicamos event.preventDefault().

document.addEventListener('DOMContentLoaded', function() {
    var linkElement = document.querySelector('#target-link');
    
    linkElement.addEventListener('click', function(e) {
        // Bloqueia o redirecionamento do href
        e.preventDefault();
        console.log('Comportamento padrão cancelado.');
    });
});

Neste caso, a propagação continua ocorrendo normalmente (os consoles dos divs pais serão executados), mas o navegador não realizará a navegação para a URL do link, mantendo o usuário na página atual.

Tags: javascript DOM event-bubbling event-propagation stoppropagation

Publicado em 6-27 00:13