Eventos em JavaScript
Na porta do apartamento há uma campainha. O botão é #bell e nele está escrito press. Por baixo, #chime ainda diz silent. No HTML não há atributo onclick, por isso bell.onclick começa como null.
Uma armadilha antiga: typeof null em JavaScript é "object". Logo typeof bell.onclick também é "object", não "null" nem "undefined". A comparação bell.onclick === null é verdadeira.
Pôr uma função em onclick não faz tocar. O texto fica silent até bell.click() executar a função que está no lugar. O lugar guarda uma função. Se atribuíres uma segunda, a primeira sai. Um clique não corre as duas. addEventListener é a página seguinte; ali os ouvintes empilham-se. Esta página não o chama.
bell.onclick = null esvazia o lugar. Um clique a seguir não mexe no texto. Dentro da função, this é o botão, portanto this.id é bell. A palavra do botão continua press. O script da página clica uma vez. A linha por baixo da campainha é dong / 1 / bell. Aqui não se cria um elemento nem se define uma propriedade CSS.
Um lugar no botão
A página anterior criava nós li com createElement e colocava-os com append, prepend e insertBefore. Aqui não se cria um nó nem se lê children. A página de antes escreveu style e classList numa amostra de tinta. Aqui não se atribui style. getElementById só te dá o botão e o parágrafo. A novidade é a propriedade onclick: uma função, ou null.
O que está no lugar
O botão começa com press e por baixo está silent. Lê as linhas por ordem. Cada excerto parte deste botão novo, salvo a linha da página, que é a demo de baixo. Essa demo não atribui null.
📊 O que está no lugar
| Momento | O que onclick guarda |
Texto da campainha | Confusão fácil |
|---|---|---|---|
| antes de qualquer atribuição | null; typeof é "object" |
silent | ler typeof como "null" |
depois da função ding, antes de click |
uma função | silent | achar que a atribuição já toca |
depois de click com ding |
essa função | ding | o texto do botão passar a ding |
dong substitui ding e depois um click |
a função dong, não ding | dong | as duas funções a correr |
onclick = null e depois click, botão novo |
null; typeof é "object" |
silent | um lugar vazio que ainda toca |
script da página, um click |
uma função; this.id é bell |
dong | a linha a acabar em silent |
onclick é uma propriedade do elemento. Sem handler, o valor é null, e typeof null continua "object". Usa === null para saber que o lugar está vazio. A atribuição guarda a função. Não a chama. bell.click() dispara um clique e executa a função que estiver no lugar nesse momento. O texto do próprio botão não muda. Uma segunda atribuição escreve por cima da propriedade. Se guardaste um nome para a primeira função, o objeto continua na memória, mas a propriedade já não aponta para ele. onclick = null tira o handler. Um atributo HTML onclick encheria o mesmo lugar; este botão não o tem. Uma arrow function neste lugar não põe this no botão. Esta página usa uma function normal.
O lugar começa vazio
O ficheiro abre com o botão e o parágrafo. Ainda não há nada atribuído. Estas quatro saídas perguntam a propriedade, o seu typeof, o texto da campainha e a palavra do botão.
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
console.log(bell.onclick);
console.log(typeof bell.onclick);
console.log(chime.textContent);
console.log(bell.textContent);
As saídas são null, object, silent e press. O lugar está vazio. typeof não imprime a palavra null. O botão e o parágrafo ainda mostram as palavras da marcação.
A função espera
onclick = function ... guarda a função. O corpo não corre nessa linha. A campainha continua silent e a propriedade já não é null.
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "ding";
};
console.log(typeof bell.onclick);
console.log(chime.textContent);
console.log(bell.onclick === null);
As saídas são function, silent e false. Há uma função no lugar. O parágrafo não mudou, porque ninguém chamou a função.
click executa a que está lá
bell.click() executa o handler atual. A campainha passa a ding. O texto do botão fica press. Depois do clique o lugar continua com uma função.
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "ding";
};
bell.click();
console.log(chime.textContent);
console.log(bell.textContent);
console.log(typeof bell.onclick);
As saídas são ding, press e function. Um clique, uma mudança, e a mudança está no parágrafo. A palavra press continua no botão.
A segunda função substitui a primeira
Este excerto volta a começar no botão novo. Primeiro guarda-se ding, depois escreve-se dong por cima, e só então vem um click. Não há clique entre as duas atribuições, por isso nesta passagem a campainha nunca fica ding. Depois do clique fica dong. bell.onclick === ding é false. bell.onclick === dong é true.
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
function ding() {
chime.textContent = "ding";
}
function dong() {
chime.textContent = "dong";
}
bell.onclick = ding;
bell.onclick = dong;
bell.click();
console.log(bell.onclick === ding);
console.log(bell.onclick === dong);
console.log(chime.textContent);
As saídas são false, true e dong. O nome ding ainda aponta para uma função. A propriedade não. Um clique executou só dong.
null esvazia o lugar
Corre isto no botão novo. Atribui-se uma função e apaga-se antes de qualquer clique. bell.click() depois de null não escreve dong. A campainha fica silent. typeof volta a ser object, porque o valor é null.
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "dong";
};
bell.onclick = null;
bell.click();
console.log(bell.onclick);
console.log(typeof bell.onclick);
console.log(chime.textContent);
As saídas são null, object e silent. A função que escreveria dong não está no lugar na hora do clique. A demo de baixo não esvazia o lugar.
Uma linha por baixo da campainha
O script está no fim de body, depois do botão e do parágrafo. Guarda uma função e chama click uma vez. Dentro da função, taps passa de 0 a 1, a campainha passa a dong, e this.id é escrito em bell.dataset.who. A linha junta o texto da campainha, a contagem e esse id. Não escreve o texto do botão.
<!DOCTYPE html>
<html>
<head>
<title>events — page</title>
</head>
<body>
<button id="bell" type="button">press</button>
<p id="chime">silent</p>
<p id="line">…</p>
<script>
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
let taps = 0;
bell.onclick = function () {
taps = taps + 1;
chime.textContent = "dong";
bell.dataset.who = this.id;
};
bell.click();
document.getElementById("line").textContent =
chime.textContent + " / " + taps + " / " + bell.dataset.who;
</script>
</body>
</html>
A linha fica dong / 1 / bell. A campainha é dong, não silent. O número é 1 porque o script clica uma vez. O último pedaço é o id do botão, vindo de this dentro do handler, não a palavra press. No botão continua press. A página seguinte trata dos ouvintes de eventos. A ferramenta principal dela não é este único lugar de onclick.
Cinco verificações
- Lê
onclick,typeof bell.onclick, o texto da campainha e o do botão. Os valores são null, object, silent e press. - Atribui a função ding e não cliques.
typeofé function, a campainha fica silent eonclick === nullé false. - Chama
bell.click()com essa função ding. A campainha é ding, o botão é press etypeofé function. - Atribui ding, depois dong, e faz um clique.
onclick === dingé false,onclick === dongé true e a campainha é dong. - Num botão novo, atribui uma função, põe
onclicka null e clica. Os valores são null, object e silent. A linha da página: dong / 1 / bell.
Onde esta campainha engana
No botão continua press. No lugar estava a função errada, ou o lugar estava vazio.
- Ler
typeof bell.onclickcomo"null"quando o valor énull - Esperar que a própria atribuição ponha a campainha em ding
- Esperar que
dingedongcorram juntas num clique depois da segunda atribuição - Esperar que o texto do botão passe a ding
- Esperar que
clickmude a campainha depois deonclick = null - Usar uma arrow function e esperar que
this.idseja bell - Ler
event.targetaqui; estas funções não recebem argumento, e o objeto do evento fica para uma página seguinte - Chamar
addEventListeneraqui; a página seguinte empilha ouvintes - Construir o botão com
createElement; isso era a página anterior - Ler a linha como silent / 0 / press
O que levas
- Sem handler,
bell.onclické null etypeof bell.onclické object - Atribuir uma função deixa a campainha silent até ao
click bell.click()com a função ding põe a campainha em ding e deixa o botão em press- A segunda atribuição substitui a primeira, por isso um clique só executa dong
onclick = nulle depoisclicknum botão novo deixa a campainha silent- A linha da página é dong / 1 / bell, e
this.iddentro do handler é bell
🧠 Teste Seu Conhecimento
Teste Seu Conhecimento
Desafie-se com este questionário interativo e veja o quão bem você entende o tópico
📝 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