Todo mundo que leva a experiência de uso da sua página um pouco a sério já se pegou pensando “uso um plugin pronto ou faço eu mesmo?” e caso cogite usar algo já pronto, acaba em dúvida sobre quais das várias opções usar.
Esses dias eu resolvi estudar o código de algumas opções disponíveis. Fiquei com medo.
Existem algumas falhas que nós desenvolvedores cometemos no desenvolvimento usando jQuery que são críticas e comuns. Hoje eu quero falar sobre uma delas em especial:
Excesso de event listeners pela página
Acho que todo mundo já escreveu um código similar a este:
$( '.foo' ).click( callback );
Você sabe o que esse código faz? Ele coloca em todos os elementos com a classe foo da sua página um event listener que dispara um callback handler sempre que o usuário clicar nele. No caso esse listener dispara a função callback. Legal e útil, né?
Agora imagine que você tenha 100 elementos com a classe foo. Serão 100 event listeners para o navegador tomar conta. Imagine que você coloque outros listeners para outros eventos e seletores. Dá pra perceber que essa conta não escala muito bem, né?
A melhor maneira de resolver isso é com event delegation.
Event Delegation
Vamos supor que nossa class foo seja aplicada à <tr>
de um tipo de tabela específica. Algo assim:
<table class="tar"> <tr class="foo">...</tr> <tr class="foo">...</tr> ... </table>
Se a gente colocar um listener diretamente na class da tabela (.tar) mandando ele ouvir os eventos internos que ocorrerem nos elementos (.foo), vamos reduzir o número de listeners espalhados pela página.
Como se faz isso, Léo?
Assim:
$( '.tar' ).on( 'click', '.foo', callback );
Essa linha de código basicamente diz: sempre que houver um evento de clique nos elementos com classe tar selecionados, verifique se esse evento foi disparado por um elemento interno com a classe foo. Se sim, execute a função callback.
Isso pode ser feito pois os eventos do DOM normalmente são transmitidos (ou propagam) (ou propagam) à todos os seus elementos pais na árvore DOM. Esse é o caso do evento de clique.
Logo, o exemplo acima teria quase o mesmo efeito caso fosse escrito desse jeito:
$( document ).on( 'click', '.foo', callback );
Você pode adicionar um event listener para responder a cliques no documento inteiro e só executar o callback caso o clique tenha ocorrido em elementos especificados, nesse caso ‘_.foo_’.
Lembra que a gente está falando de melhora de desempenho? Se você forçar o navegador a ouvir todos os cliques na sua página e só executar em casos específicos, você estará disperdiçando recursos. Não faça isso, a não ser que seja extremamente necessário. Busque sempre fixar seus eventos em elementos wrappers, como aquele