Carregando...

O objeto event

Na parede do museu há uma placa. A caixa de fora é #wall. Dentro, #plaque guarda um link, #seal. No link está open, e href é /wing. Abaixo, #slip diz blank.
O navegador entrega um objeto à função. O parâmetro chama-se event. event.type é o tipo do evento. Um clique deixa essa cadeia em click. event.target é o elemento onde o clique caiu. event.currentTarget é o elemento onde este ouvinte está. Os dois só coincidem quando o clique e o ouvinte partilham um elemento.
O selo é um link. preventDefault cancela o salto para /wing. Depois da chamada, event.defaultPrevented é true. Sem a chamada, a bandeira fica false. O clique segue para fora: selo, placa, parede. stopPropagation na placa corta essa viagem, e o ouvinte da parede não corre.
O script da página clica no selo uma vez. A linha sob a placa é click / seal / plaque / true / quiet. Aqui não se atribui onclick, não se chama removeEventListener e não se cria um elemento.

O objeto que o navegador passa

A página anterior era o cabide. wool e silk não tinham parâmetro e não liam este objeto. A linha deles era wool silk / 2 / peg. A página da campainha atribuía onclick e lia this. Esta página não. getElementById só te dá a parede, a placa, o selo e a ficha.
addEventListener continua só a guardar a função. O objeto chega quando o clique executa a função, não ao adicionar o ouvinte. Lê currentTarget dentro da função. Depois do regresso, essa propriedade é null.

O que um clique informa

A ficha começa em blank. O texto do link continua open. Lê as linhas por ordem. Cada trecho parte dessa parede nova, salvo a linha da página, que é a demo em baixo. Essa demo não chama removeEventListener.

📊 O que um clique informa

Momento O que lês Texto da ficha Confusão fácil
ouvinte no selo, seal.click(), ler o tipo event.type click ler o id como se fosse o tipo
ouvinte na placa, clique no selo, target event.target.id seal ler currentTarget
o mesmo clique, currentTarget event.currentTarget.id plaque ler target
preventDefault no selo, depois a bandeira event.defaultPrevented true achar que o link ainda sai
sem preventDefault event.defaultPrevented false achar que todo ouvinte cancela o link
stopPropagation na placa, a parede também ouve marks unidos plaque esperar plaque wall
script da página, um click a linha click / seal / plaque / true / quiet a linha acabar em wall

Um clique no selo é um só objeto. Todos os ouvintes no caminho veem o mesmo. type não muda. target não muda. currentTarget muda: é o elemento cujo ouvinte está a correr agora.
preventDefault fala com a ação predefinida do navegador. Neste link, essa ação é seguir /wing. A chamada não tira um ouvinte da lista. stopPropagation fala com a viagem. Não cancela o link. Chamar um não é chamar o outro.
join(" ") só põe um espaço entre palavras que já estão em marks. Aqui não se junta uma lista vazia. A ficha começa com a palavra blank e só muda dentro de um ouvinte, ou no script da página depois do clique.

O tipo

O ouvinte está no selo. A função nomeia o parâmetro event e escreve event.type na ficha. Depois corre seal.click().

Ler o tipo

javascript
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readType(event) {
slip.textContent = event.type;
}
seal.addEventListener("click", readType);
seal.click();
console.log(slip.textContent);

A saída é click. O tipo é a espécie do evento, não o id nem a palavra open.

O elemento onde o clique caiu

Parede nova. O ouvinte está na placa, não no selo. O clique cai na mesma no selo. event.target é esse elemento, logo event.target.id é seal.

Ler o target

javascript
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readTarget(event) {
slip.textContent = event.target.id;
}
plaque.addEventListener("click", readTarget);
seal.click();
console.log(slip.textContent);

A saída é seal. O elemento do ouvinte é a placa. target não informa a placa. Informa o elemento sob o clique.

Onde o ouvinte está

A mesma parede nova, ouvinte ainda na placa, clique ainda no selo. A ficha escreve os dois id, target primeiro, depois currentTarget.

Ler os dois id

javascript
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readWhere(event) {
slip.textContent = event.target.id + " " + event.currentTarget.id;
}
plaque.addEventListener("click", readWhere);
seal.click();
console.log(slip.textContent);

A saída é seal plaque. A primeira palavra é o clique. A segunda é o elemento dono deste ouvinte. Põe o ouvinte no selo e clica no selo: os dois id são seal, porque o clique e o ouvinte partilham um elemento. Esta leitura usa a placa, por isso os id diferem. Lê currentTarget dentro da função. Ao regressar, é null.

Cancelar o link

O href do selo é /wing. A ação predefinida desse clique é seguir o link. preventDefault cancela essa ação. Não remove o ouvinte. Logo a seguir, event.defaultPrevented é true.

Cancelar o link

javascript
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function hold(event) {
event.preventDefault();
slip.textContent = String(event.defaultPrevented);
}
seal.addEventListener("click", hold);
seal.click();
console.log(slip.textContent);

A saída é true. Sem preventDefault, a mesma leitura é false. A ficha diria false e a ação do link continuaria. stopPropagation não põe esta bandeira.

O clique viaja para fora

O selo está na placa, e a placa na parede. Um clique no selo chega ao ouvinte da placa e depois ao da parede, salvo se a viagem for cortada. stopPropagation na placa corta-a. A função da parede não corre. preventDefault não corta a viagem.

Cortar a viagem

javascript
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let marks = [];
function onPlaque(event) {
marks.push("plaque");
event.stopPropagation();
}
function onWall() {
marks.push("wall");
}
plaque.addEventListener("click", onPlaque);
wall.addEventListener("click", onWall);
seal.click();
slip.textContent = marks.join(" ");
console.log(slip.textContent);

A saída é plaque. A palavra wall não entra em marks. Sem stopPropagation, o mesmo clique escreveria plaque wall. A demo de baixo corta a viagem e também cancela o link.

Uma linha sob a placa

O script fica no fim do body, depois de a parede e os parágrafos existirem. O ouvinte do selo chama preventDefault. O da placa chama stopPropagation e guarda o tipo, o id de target, o id de currentTarget e a bandeira. O da parede poria heard em wall, mas a viagem já está cortada, por isso heard fica quiet. A linha escreve-se depois de seal.click(), quando a parede já teve a sua vez.

Demo da página — placa do museu

html
<!DOCTYPE html>
<html>
<head>
<title>event-object — page</title>
</head>
<body>
<div id="wall">
<div id="plaque">
<a id="seal" href="/wing">open</a>
</div>
</div>
<p id="slip">blank</p>
<p id="line">…</p>
<script>
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let kind = "";
let from = "";
let on = "";
let held = "";
let heard = "quiet";
seal.addEventListener("click", function (event) {
event.preventDefault();
});
plaque.addEventListener("click", function (event) {
event.stopPropagation();
kind = event.type;
from = event.target.id;
on = event.currentTarget.id;
held = String(event.defaultPrevented);
});
wall.addEventListener("click", function () {
heard = "wall";
});
seal.click();
slip.textContent = kind + " " + from + " " + on;
document.getElementById("line").textContent =
kind + " / " + from + " / " + on + " / " + held + " / " + heard;
</script>
</body>
</html>

A linha fica click / seal / plaque / true / quiet. O tipo é click. O id de target é seal. O id de currentTarget é plaque, porque esse ouvinte está na placa. A bandeira é true, porque o ouvinte do selo chamou preventDefault antes de a placa a ler. A última ficha é quiet, não wall, porque stopPropagation correu na placa. O texto open não está na linha. A ficha passa a click seal plaque. A página seguinte é a delegação. O selo já está na marcação. Aqui não se acrescenta um filho depois do ouvinte.

Cinco verificações na placa

  1. Põe o ouvinte no selo e clica. A ficha é click.
  2. Põe o ouvinte na placa, clica no selo e lê event.target.id. A ficha é seal.
  3. O mesmo ouvinte escreve os dois id. A ficha é seal plaque. Um ouvinte no próprio selo escreveria seal seal.
  4. Chama preventDefault e lê event.defaultPrevented. A ficha é true. Sem a chamada, é false.
  5. Chama stopPropagation na placa enquanto a parede também ouve. marks junta-se em plaque. Lê a linha: click / seal / plaque / true / quiet.

Onde esta placa engana

O link continua a dizer open. A ficha não é o texto do link.

  • Esperar que o argumento da função seja o elemento selo, e não o objeto do evento
  • Ler event.target quando querias o elemento do ouvinte
  • Ler event.currentTarget quando querias o elemento sob o clique
  • Esperar que preventDefault retire o ouvinte, como removeEventListener no cabide
  • Esperar que stopPropagation cancele o salto para /wing
  • Esperar que o ouvinte da parede corra depois de stopPropagation na placa
  • Ler event.currentTarget depois do regresso da função e esperar plaque
  • Atribuir onclick, ou ler this e typeof null; isso era a campainha
  • Construir o link com createElement; isso era uma página anterior
  • Ler a linha como se acabasse em wall, ou como wool silk / 2 / peg

O que fica

  • event.type depois de um clique é click
  • Ouvinte na placa e clique no selo: event.target.id é seal
  • Nesse mesmo clique, event.currentTarget.id é plaque
  • Com o ouvinte no selo, target e currentTarget são ambos seal
  • preventDefault põe event.defaultPrevented em true; sem a chamada fica false
  • stopPropagation na placa impede o ouvinte da parede
  • A linha é click / seal / plaque / true / quiet

🧠 Teste Seu Conhecimento

Pronto para Começar

Teste Seu Conhecimento

Desafie-se com este questionário interativo e veja o quão bem você entende o tópico

❓
8
Perguntas
🎯
70%
Para Passar
♾️
∞
Tempo
🔄
∞
Tentativas

📝 Instruções

  • Leia cada pergunta cuidadosamente
  • Selecione a melhor resposta para cada pergunta
  • Você pode refazer o quiz quantas vezes quiser
  • Seu progresso será mostrado no topo