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 ou mais recente, o Firefox 50 ou mais recente e a pré-visualização de tecnologia 7 ou mais recente 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.