Delegação de eventos: ouvindo eventos de forma eficiente
Descubra uma técnica para gerenciar eventos em múltiplos elementos de forma otimizada.
Você já aprendeu a usar addEventListener em elementos específicos.
Agora imagine uma lista com 100 botões de remover.
Adicionar 100 listeners funciona… mas não é o jeito mais eficiente.
É aqui que entra a delegação de eventos.
Ideia principal
Em vez de colocar um listener em cada filho, você coloca um listener no elemento pai e trata os cliques dos filhos usando o objeto event.
Analogia simples:
em vez de um segurança por porta, você coloca um segurança na entrada principal observando quem entrou e o que fez.
Por que isso funciona?
Porque os eventos no DOM “sobem” na árvore (isso se chama propagação/bubbling).
Exemplo:
- clicou no botão
- evento acontece no botão
- depois sobe para o
li - depois sobe para o
ul - depois para elementos acima…
Então, se o pai está ouvindo clique, ele consegue detectar cliques dos filhos.
Exemplo sem delegação (menos eficiente)
const botoes = document.querySelectorAll(".btn-remover");
botoes.forEach(function (botao) {
botao.addEventListener("click", function () {
botao.parentElement.remove();
});
});
Problema: se novos botões forem criados depois, eles não terão listener automaticamente.
Exemplo com delegação (mais eficiente)
HTML:
<ul id="lista">
<li>Item 1 <button class="btn-remover">Remover</button></li>
<li>Item 2 <button class="btn-remover">Remover</button></li>
</ul>
JavaScript:
const lista = document.getElementById("lista");
lista.addEventListener("click", function (e) {
if (e.target.matches(".btn-remover")) {
const item = e.target.closest("li");
item.remove();
}
});
O que está acontecendo?
- O listener está no
ul(lista) e.targetdiz onde o clique realmente aconteceumatches(".btn-remover")verifica se foi no botão certoclosest("li")encontra o item da lista para remover
Vantagens da delegação
- Menos listeners no código
- Melhor organização
- Melhor desempenho em listas grandes
- Funciona com elementos criados dinamicamente depois
Cuidados importantes
- Sempre filtre com
matchesouclosest, para não reagir a cliques errados. - Escolha um pai adequado (nem amplo demais, nem específico demais).
- Em estruturas complexas, teste bem para evitar efeitos inesperados.
Mini exemplo com itens dinâmicos
Mesmo se você adicionar novos itens depois, o listener no pai continua funcionando:
const novoItem = document.createElement("li");
novoItem.innerHTML = 'Item novo <button class="btn-remover">Remover</button>';
lista.appendChild(novoItem);
Não precisa adicionar novo addEventListener no botão recém-criado.
Resumo da lição
- Delegação de eventos = ouvir no pai e tratar no filho.
- Funciona graças à propagação (bubbling).
- Use
e.target,matcheseclosestpara identificar o alvo correto. - Excelente para listas, tabelas, menus e elementos dinâmicos.
- É uma técnica essencial para código mais eficiente e escalável.