# Delegação de Evento (Event Delegation) em JavaScript puro

> Domine Event Delegation em JavaScript puro sem jQuery. Aprenda a técnica essencial para melhorar performance e gerenciar eventos dinamicamente.

URL: https://dpw.dev/javascript/delegacao-de-evento-event-delegation-javascript/  
Publicado em: 2016-04-12  
Categoria: javascript  
Tags: jquery, performance  
Autor: Tárcio Zemel

Se você usa [jQuery](/tag/jquery) para lidar com a camada de comportamento de seus sites/apps, muito provavelmente já se deparou (e se depara) com situações em que o uso de **Delegação de Evento** ou **Event Delegation** é indispensável para não impactar negativamente na [performance](/tag/performance). De fato, saber como usar eventos com o [método .on() de jQuery](http://api.jquery.com/on/) é uma das primeiras lições ao se aprender a usar a biblioteca e, ali mesmo, [é mostrado como realizar a delegação de eventos de maneira bem simples](http://api.jquery.com/on/#direct-and-delegated-events).

Mas você sabe como fazer a delegação de eventos em JavaScript puro? Não é tão simples quanto usar uma biblioteca parruda como jQuery, mas certamente é bastante acessível e possível de se fazer no dia-a-dia. Neste artigo, aprenda mais sobre **Delegação de Evento** (Event Delegation) em **JavaScript puro** (Vanilla JavaScript).

> Artigo baseado em [How JavaScript Event Delegation Works](https://davidwalsh.name/event-delegate).

Uma das metodologias "quentes" no mundo JavaScript é a **delegação de evento**. E por boas razões. Delegação de evento permite que você evite adicionar "ouvintes" (listeners) de eventos para nós específicos do DOM; em vez disso, o "ouvinte" (listener) de evento é adicionado a um dos pais deste(s) nó(s). Esse listener de eventos analisa os eventos que "borbulharam para cima" (bubbled) para encontrar uma correspondência em elementos filho -- se não souber bem o que é isso, [leia um excelente artigo sobre captura de eventos e bubbling em JavaScript](https://www.kirupa.com/html5/event_capturing_bubbling_javascript.htm) (em inglês). O conceito-base é bastante simples, mas muitas pessoas não entendem o quão bem Delegação de Eventos funciona e como isso impacta de maneira positiva na [performance](/tag/performance) de uma aplicação!

Por exemplo, digamos que exista uma lista com vários itens:

```html
<ul id="parent-list">
    <li id="post-1">Item 1</li>
    <li id="post-2">Item 2</li>
    <li id="post-3">Item 3</li>
    <li id="post-4">Item 4</li>
    <li id="post-5">Item 5</li>
    <li id="post-6">Item 6</li>
</ul>
```

Consideremos, também, que alguma coisa precisa acontecer quando cada elemento filho é clicado. Você pode adicionar um listener de eventos separado para cada elemento `<li>` individualmente, mas e se, por quaisquer outras interações/motivos, elementos `<li>` são adicionados e/ou removidos da lista? Adicionar e remover listeners em tempo real seria um pesadelo, especialmente se a adição e remoção de código se dá em diferentes partes da aplicação -- o que é bastante comum. A melhor solução é adicionar um listener de eventos para o pai, o elemento `<ul>`! Mas, se você adicionar o ouvinte de eventos para o pai, como vai saber qual elemento foi clicado?

Simples: quando o evento borbulha pra cima (bubbles up) até o elemento `<ul>`, é possível verificar a propriedade `target` para obter a referência sobre o nó que foi clicado. Aqui está um trecho muito básico JavaScript que ilustra a delegação de evento:

```javascript
// Pega o elemento e adiciona um listener para click
document.querySelector( '#parent-list' ).addEventListener( 'click', function( e ) {
    // e.target é o elemento clicado
    // se ele for um item de lista
    if ( e.target && e.target.nodeName == 'LI' ) {
        // Item da lista encontrado!  Mostrando o ID!
        console.log( 'Item ', e.target.id.replace( 'post-', ''), ' foi clicado!' );
    }
}, false);

```

Começa-se por adicionar um listener de `click` no elemento pai. Quando este listener é acionado, verifica-se o elemento do evento para garantir que ele é o tipo de elemento a reagir. Se é um elemento `<li>`, bum: tem-se o que é preciso; se não é um elemento `<li>`, o evento pode ser ignorado.

Para fixar, partamos para outro exemplo, dessa vez com uma `div` com muitos filhos, mas o que realmente importa é um elemento `<a>` com a classe `classA`. Como você faria? Qual seria o código para, dentre todos os nós-filho dentro desta `div` possíveis de serem clicados, saber precisamente quando o que tem determinada classe o foi? Obviamente, identificando se o elemento clicado em questão possui tal classe:

```javascript
// Pega o elemento e adiciona um listener para click
document.querySelector( '#myDiv' ).addEventListener( 'click', function( e ) {
    // e.target é o elemento clicado
    if ( e.target && e.target.classList.contains( 'classA' ) ) {
        console.log( 'Link clicado!' );
    }
}, false);

```

Simples, hã? ;-)

## Conclusão sobre Delegação de Evento (ou Events Delegation)

A maioria das bibliotecas JavaScript, como jQuery, já possuem delegação de evento para se trabalhar. Então, mesmo que não se esteja trabalhando com JavaScript puro, em casos em que é preciso adicionar muitos eventos para elementos, sempre que possível use delegação de eventos.

Quando projeto pedir e/ou for do seu gosto pessoal (ou da equipe) trabalhar com vanilla JavaScript, agora você já sabe como lidar com Delegação de Eventos. É quase tão fácil quanto ao usar bibliotecas JS e, na quase totalidade dos casos, bem mais performático!

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
