Na maior parte das vezes as manipulações que fazemos são reações a ações do usuário na página. Por exemplo, se o usuário clicar numa lixeira, algo é deletado. Os eventos possíveis são vários: eventos de mouse, teclado, de submit, etc.
Após obter a referência do elemento onde queremos que o evento aconteça, podemos adicionar um event listener
(escutador de evento). Assim, o elemento fica na escuta para quando o evento for disparado. O terceiro passo é implementar uma função de callback quando o evento acontecer (por exemplo, quando o botão for clicado)
button = document.querySelector('button')
\\ obtém referência do botão
button.addEventListener('click', () => { console.log('Clicou no botão')})
\\ acrescenta o evento que queremos escutar (1o parâmetro) e a função de callback que deve ocorrer após o click.
Para uma lista com os diversos event listeners
, clique aqui.
Quando um evento acontece no browser, dentro da função de callback da
addEventListener
o browser disponibiliza um objeto no parâmetro da função: oevent
. Esse objeto tem informações sobre o evento que aconteceu. Um exemplo é a propriedadetarget
, que armazena a referência do elemento em que o evento ocorreu.
lis.forEach( li => {
li.addEventListener('click', event => {
console.log(event.target)
})
})
\\ mostra no console a referência da `li` que foi clicada
O elemento onde um evento acorreu se torna a
target
. Quando isso acontece, o JS procura se existe umeventListener
nesse evento para disparar a função de callback atrelada. Mas não é só isso que acontece: o evento é propagado a partir dotarget
onde aconteceu pela árvore do dom até o topo.
li.addEventListener('click', event => {
const clickedElement = event.target
clickedElement.remove()
})
// ao ser clicado, o elemento li será removido...
ul.addEventListener('click', () => console.log('event listener foi disparado'))
// ...e o console mostra a mensagem, pois a ul (elemento pai da "li") teve seu "event listener" propagado.
Essa propagação é chamada de event bubbling
. O evento é iniciado no target
(elemento onde o evento foi adicionado), e se propaga para os pais, fazendo com que os callbacks de eventos que estes pais tenham sejam disparados também.
Por meio do método stopPropagation
do objeto event
é possível impedir que o evento se propague para os elementos pais.
li.addEventListener('click', event => {
const clickedElement = event.target
clickedElement.remove()
event.stopPropagation()
})
// ao ser clicado, o elemento li será removido...
ul.addEventListener('click', () => console.log('event listener foi disparado'))
// ...e o evento não será propagado. A mensagem no console será exibida somente se o click ocorrer na `ul`.
Isso é importante para evitar comportamentos inesperados quando se trata de propagação de eventos.
Adicionar eventos em cada elemento (por exemplo, utilizando forEach
para iterar e adicinar eventos em cada elemento) em escala pode afetar a performance - o que não é uma boa prática.
ul.addEventListener('click', event => {
console.log(event.target)
})
// obtém a referência dos elementos clicados (por exemplo: 'li' filha)
por meio da propagação de eventos que é disparada.
É possível checar por meio da propriedade tagName
se o clique aconteceu no elemento que você esperava.
ul.addEventListener('click', event => {
const clickedElement = event.target
if(clickedElement.tagName === 'LI') {
clickedElement.remove()
}
})
Formulários existem para captar informações de um usuário. Um exemplo pode ser um formulário de feedback - para capturar essas informações usamos eventos - principalmente eventos de
submit
(eventos de envio). Clicar num botão de enviar dispara o evento de click mas também dispara um evento desubmit
doform
. Nesse caso podemos setar um listener de evento que reage ao envio das informações. Quando oform
for enviado podemos captar as informações preenchidas. Outros tipos de eventos são os de teclado (quando usuário pressiona ou solta a tecla).
Quando queremos escutar um evento de usuário é importante atrelar o evento de escuta ao form (e não ao botão, como vínhamos fazendo até então). Pois o que queremos é escutar o envio das informações, e não o botão (que é apenas um elemento do form).
const form = document.querySelector('.signup-form')
form.addEventListener('submit', event => {
event.preventDefault()
})
// evita comportamento padrão de recarregar a página no momento do 'submit'
Para obter a referência do que foi inserido no formulário podemos utilizar algumas formas diferentes. Por exemplo, utilizando a ID na tag input:
const form = document.querySelector('.signup-form')
const usernameInput = document.querySelector('#username')
form.addEventListener('submit', event => {
event.preventDefault()
console.log(usernameInput.value)
})
// mostra no console o valor do input.
Outra forma é usar a referência do form
para acessar o ID
ou name
.
form.addEventListener('submit', event => {
console.log(form.username.value)
})
Ainda é possível utilizar event.target
ao invés de form
para ter acesso ao username e portanto do seu valor.
form.addEventListener('submit', event => {
console.log(event.target.username.value)
})
Este evento vai executar uma função de callback toda vez que uma tecla pressionada for liberada (o momento exato que a tecla volta para cima).
const form = document.querySelector('form')
form.idInput.addEventListener('keyup', event =>
console.log(event.target.value))
// quando pressionar e liberar a tecla, a função é executada e o valor do input é exibido no console.
Exemplo de validação de input em tempo real:
form.idInput.addEventListener('keyup', event => {
if (isValidUsername) {
form.idInput.setAttribute('class', 'success')
return
}
form.idInput.setAttribute('class','error')
})