Teste rápido: qual é a finalidade do terceiro parâmetro transmitido para
addEventListener()
?
Não se sinta envergonhado se você achou que addEventListener()
só tomou dois
parâmetros, ou talvez apenas fixou no código um valor de false
, entendendo vago
que tem algo a ver com... bolhas?
Um addEventListener() mais configurável
O método addEventListener()
evoluiu muito desde os primórdios da
Web, e a nova funcionalidade é configurada por uma versão sobrecarregada desse
terceiro parâmetro. Mudanças recentes na definição do método permitem
que os desenvolvedores ofereçam outras opções usando um objeto de configuração,
permanecendo compatíveis com versões anteriores quando há um parâmetro booleano ou quando uma
opção não é especificada.
Temos o prazer de anunciar que o Chrome 55 adiciona suporte à opção once
nesse
objeto de configuração, junto com as opções passive
(implementadas no Chrome 51)
e capture
(implementadas no Chrome 49). Exemplo:
element.addEventListener('click', myClickHandler, {
once: true,
passive: true,
capture: true
});
É possível misturar e combinar essas opções conforme apropriado com seu caso de uso.
Os benefícios de fazer a limpeza depois de si
Essa é a sintaxe para usar a nova opção once
, mas o que isso significa? Em resumo, ele oferece um listener de eventos personalizado para os casos de uso
"um e concluído".
Por padrão, os listeners de eventos persistem após a primeira vez que são chamados, que
é o que você quer para alguns tipos de eventos, como botões que podem ser clicados várias
vezes, por exemplo. No entanto, para outros usos, não é necessário manter um listener de eventos
e pode levar a um comportamento indesejável se você tiver um
callback que precisa ser executado apenas uma vez. Os desenvolvedores íntegros sempre tiveram a
opção de usar removeEventListener()
para fazer a limpeza explicitamente, seguindo
padrões como:
element.addEventListener('click', function cb(event) {
// ...one-time handling of the click event...
event.currentTarget.removeEventListener(event.type, cb);
});
O código equivalente, que usa o novo parâmetro once
, é mais limpo e
não força você a acompanhar o nome do evento (event.type
, no
exemplo anterior) ou uma referência à função de callback (cb
):
element.addEventListener('click', function(event) {
// ...one-time handling of the click event...
}, {once: true});
Limpar os manipuladores de eventos também pode aumentar a eficiência da memória, destruindo o escopo associado à função de callback, permitindo que todas as variáveis capturadas nesse escopo sejam coletadas como lixo. Confira um exemplo em que isso faria diferença:
function setUpListeners() {
var data = ['one', 'two', '...etc.'];
window.addEventListener('load', function() {
doSomethingWithSomeData(data);
// data is now part of the callback's scope.
});
}
Por padrão, o callback do listener de eventos load
permanecerá no escopo quando terminar a execução, mesmo que nunca seja usado novamente. Como a variável data
é usada dentro do callback, ela também permanecerá no escopo e nunca será
coletada de lixo. No entanto, se o callback for removido pelo parâmetro once
, a função em si e qualquer item que seja mantido ativo pelo escopo poderão
se tornar candidatos à coleta de lixo.
Suporte ao navegador
O Chrome 55, o Firefox 50 e a prévia de tecnologia 7 e mais recentes do Safari
têm suporte nativo para a
opção once
.
Muitas bibliotecas de interface JavaScript oferecem métodos convenientes para criar listeners
de eventos, e algumas têm atalhos para definir eventos únicos. O mais notável
é o método one()
do jQuery. Um polyfill
também está disponível como parte da
biblioteca dom4
de Andrea Giammarchi (links em inglês).
Até logo!
Agradecemos a Ingvar Stepanyan pelo feedback sobre o código de exemplo desta postagem.