# 8.10 - Aprofundando nos eventos

## 🌊 Event Bubbling e Outras Aventuras com Eventos

Agora que você já sabe **como lidar com eventos**, vamos explorar um comportamento mais avançado (e às vezes confuso 😅) chamado ***event bubbling***.

Sim! Os eventos no DOM não agem isoladamente — eles **sobem** e **descem** na árvore de elementos da página. Isso é super importante para entender **por que às vezes seu evento parece acontecer mais de uma vez** ou em lugares que você não esperava.

***

### 🌪️ O que é *Event Bubbling*?

Imagine que você clicou em um botão. Esse botão está dentro de um formulário, que está dentro de uma `div`, que está dentro do `body`.

👉 Quando você clica, o evento **não para no botão**. Ele **sobe (bubble)** por todos os elementos-pai, até chegar no `document`.

🧱 Exemplo visual:

```
<body>
  └── <div>
        └── <form>
              └── <button> ← clique aqui!
```

Esse clique **"borbulha" de baixo para cima**: do botão → formulário → div → body → document.

***

### 🎯 Exemplo prático

```html
<div id="pai">
  <button id="filho">Clique</button>
</div>

<script>
  document.getElementById("pai").addEventListener("click", () => {
    console.log("Pai clicado!");
  });

  document.getElementById("filho").addEventListener("click", () => {
    console.log("Filho clicado!");
  });
</script>
```

🔎 Resultado ao clicar no botão:

```
Filho clicado!
Pai clicado!
```

Por quê? Porque o clique no botão também **chegou no pai**. 🧼

***

### ⛔ Evitando efeitos colaterais com `stopPropagation()`

Se você **não quiser que o evento suba**, use:

```javascript
element.addEventListener("click", (event) => {
  event.stopPropagation();
});
```

Isso **interrompe a "subida" do evento**, evitando que ele acione outros elementos pai.

***

### 👀 *Event Capturing*: O lado oposto do bubbling!

Sabia que o evento também pode ser detectado **na descida** pela árvore, antes de atingir o elemento?

✨ É o chamado **capturing phase** (ou fase de captura).

Você ativa isso com um terceiro argumento no `addEventListener`:

```javascript
element.addEventListener("click", minhaFuncao, true);
```

🔄 Comparando:

* `true` = captura → detecta o evento **descendo** a árvore
* `false` (padrão) = bubbling → detecta **subindo**

***

### ℹ️ Curiosidade útil: Por que existem o event bubbling e o event capturing?

Essas fases foram criadas para dar mais controle aos desenvolvedores na forma como os eventos são tratados.

Imagine uma árvore com milhares de elementos. Se cada elemento precisasse de seu próprio "ouvidor de eventos", o desempenho da página seria péssimo e o código ficaria complicado.

✅ O bubbling permite que você trate eventos em elementos-pai com poucas linhas de código, como quando usamos delegação de eventos.

🔍 O capturing é útil quando você quer interceptar o evento antes que ele chegue ao destino (como um guarda que intercepta antes de entrar no prédio).

Ou seja: não é só um detalhe técnico — é uma escolha de arquitetura pensada para performance, flexibilidade e clareza. 😉

***

### 🔄 Delegação de eventos (*Event Delegation*)

Sabia que você pode usar o bubbling a seu favor?

Em vez de colocar um `addEventListener` em **cada item**, você pode colocar **um só** no pai e reagir com base no `event.target`.

#### Exemplo:

```html
<ul id="lista">
  <li>Item 1</li>
  <li>Item 2</li>
</ul>

<script>
  document.getElementById("lista").addEventListener("click", (event) => {
    if (event.target.tagName === "LI") {
      console.log("Clicou em:", event.target.textContent);
    }
  });
</script>
```

🧠 Isso é **mais eficiente**, especialmente se os itens forem criados dinamicamente!

***

### 🧭 `event.target` vs `event.currentTarget`

| Propriedade     | O que representa?                            |
| --------------- | -------------------------------------------- |
| `target`        | Onde o evento **aconteceu de fato**          |
| `currentTarget` | Onde o `addEventListener` foi **registrado** |

#### Exemplo:

```javascript
element.addEventListener("click", (event) => {
  console.log("target:", event.target);
  console.log("currentTarget:", event.currentTarget);
});
```

🕵️ Use `target` para saber **quem foi clicado**\
🧱 Use `currentTarget` para saber **quem está "ouvindo"**

***

### 🔁 Comportamentos inesperados comuns

* Clicar em um botão dispara um evento no `form`, `div`, e até `body`
* Esquecer de usar `stopPropagation()` pode causar bugs difíceis de encontrar
* Usar `innerHTML` e recriar elementos pode **remover listeners**
* Usar `event.target` sem verificar a tag pode causar erros

***

### ✅ Boas práticas

| Fazer                                        | Evitar                                                     |
| -------------------------------------------- | ---------------------------------------------------------- |
| Usar delegação em listas grandes             | Adicionar centenas de listeners                            |
| Usar `stopPropagation()` com propósito claro | Usar `stopPropagation()` sem motivo (pode quebrar coisas!) |
| Verificar `event.target.tagName` ao delegar  | Assumir que o clique sempre vem do elemento certo          |

***

### 🚨 Erros comuns para evitar

* Achar que `addEventListener` só funciona no elemento clicado
* Esquecer que o evento pode subir
* Usar muitos listeners sem necessidade (problemas de performance)
* Misturar `target` e `currentTarget` nos testes

***

### 🧪 Teste na prática!

Crie um quadrado dentro de outro quadrado e adicione um `click` nos dois. Veja quem é chamado primeiro (usando bubbling) e depois inverta usando capturing. Experimente `stopPropagation()` e use `console.log()` para estudar o fluxo!
