Teste rápido: qual é a finalidade do terceiro parâmetro transmitido para
addEventListener()
?
Não se sinta envergonhado se você pensou que addEventListener()
precisava de apenas dois
parâmetros ou talvez sempre codificar um valor de false
, com uma vaga
compreensão de que isso tem algo a ver com… bolhas?
Um addEventListener() mais configurável
O método addEventListener()
percorreu um longo caminho desde os primeiros dias da
Web, e a nova funcionalidade dele é configurada por uma versão superpotência desse
terceiro parâmetro. Mudanças recentes na definição do método permitem
que os desenvolvedores ofereçam opções adicionais usando um objeto de configuração,
mantendo a compatibilidade 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
(implementada no Chrome 51)
e capture
(implementada no Chrome 49). Exemplo:
element.addEventListener('click', myClickHandler, {
once: true,
passive: true,
capture: true
});
Você pode combinar essas opções de acordo com seu caso de uso.
Os benefícios de limpar depois de si mesmo
Essa é a sintaxe para usar a nova opção once
, mas o que ela
faz? Em resumo, ele fornece um listener de eventos personalizado para casos de uso
"pronto para uso".
Por padrão, os listeners de eventos persistem após a primeira vez que são chamados, o que
é o que você quer para alguns tipos de eventos, como botões que podem ser clicados várias
vezes, por exemplo. Para outros usos, no entanto, não é necessário manter um listener de eventos
e isso pode levar a um comportamento indesejado se você tiver um
callback que só precisa ser executado uma vez. Os desenvolvedores higiênicos sempre tiveram a
opção de usar removeEventListener()
para limpar as coisas 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});
A limpeza dos manipuladores de eventos também pode oferecer eficiência de memória, destruindo o escopo associado à função de callback, permitindo que todas as variáveis capturadas nesse escopo sejam coletadas. 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
vai permanecer no escopo quando
terminar a execução, mesmo que nunca seja usado novamente. Como a variável data
é usada no callback, ela também permanece no escopo e nunca recebe a coleta de
lixo. No entanto, se o callback for removido pelo parâmetro once
, a própria função e tudo o que for mantido vivo pelo escopo dela
poderá ser candidato à coleta de lixo.
Suporte ao navegador
O Chrome 55 e versões mais recentes, o Firefox 50 e versões mais recentes e a pré-visualização de tecnologia 7 e versões 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 conhecido
é o método one()
do jQuery. Um polyfill
também está disponível como parte da
biblioteca dom4
do Andrea Giammarchi.
Obrigado
Agradecemos a Ingvar Stepanyan pelo feedback sobre o código de exemplo desta postagem.