jQuery: diferença entre bind, live, delegate, on
A biblioteca jQuery oferece diferentes formas de registrar eventos: bind, live, delegate, on… Mas quais são as diferenças? Quando devo usar cada uma destas funções?
bind
$('.classe').bind('click focus', function () {
alert('evento disparado')
})
Registra um ou mais eventos diretamente nos elementos selecionados. Registra apenas para os elementos que existem na página no momento que o bind foi chamado, ou seja, elementos que são criados posteriormente via JS não respondem ao evento. Quem chegou depois não participa da brincadeira.
live (deprecated)
$('.classe').live('click focus', function () {
alert('evento disparado')
})
Registra eventos nos elementos que casam com o seletor, atualmente e no futuro. Diferente do bind, mesmo elementos que são criados dinamicamente, depois da chamada do live, também responderão aos eventos. Esse sim, não importa a hora que você chega, se você casa com o seletor, seu evento vai ser tratado.
Como ele faz isso? Na verdade o live registra os eventos no objeto document, que contém todos os elementos da página. No exemplo acima, quando um click é disparado, o objeto document captura o evento e procura por elementos que casem com ‘.classe’, executando a ação correspondente usando cada elemento como alvo.
O preço desta facilidade é desempenho. Cada vez que um evento registrado com o live é disparado, ele faz uma busca em todo o documento para encontrar os elementos que casem com o seletor. E isso custa caro. Por isso a própria documentação do jQuery recomenda usar o delegate ao invés do live.
delegate
$('.classe-pai').delegate('a', 'click', function () {
alert('evento disparado')
})
O delegate é parecido com o live no sentido que, mesmo elementos criados depois também respondem aos eventos. A diferença é que aqui ele não usa o document como elemento raiz. Você escolhe o elemento raiz (no exemplo ‘.classe-pai’) e os elementos filhos que responderão pelo evento (no caso, ‘a’). Desta forma você tem as vantagens do live, mas restringindo o alcance a uma parte limitada do documento e assim ganhando desempenho.
Dica de performance!
O delegate é ideal para melhorar o desempenho quando você tem vários elementos na página que respondem a um evento de forma parecida.
Exemplo: Você tem 50 miniaturas de fotos de uma página, e quando clicar em cada uma delas vai abrir um overlay com a foto ampliada. Ao invés de fazer o bind em todas as fotos:
$('.miniatura').bind('click', function () {
abreFoto($(this).attr('href'))
})
Faça um delegate, usando um elemento pai das miniaturas como elemento raiz:
$('.div-miniaturas').delegate('.miniatura', 'click', function () {
abreFoto($(this).attr('href'))
})
Assim, você reduz a quantidade de eventos registrados na página de 50 para 1, ganhando bastante performance.
on (one function to rule them all)
As funções que vimos acima (exceto o live, que está com os dias contados) ainda são recomendadas para quem usa jQuery em versão anterior ao 1.7. A partir da versão 1.7 surgiu o on, que agora é a recomendação para substituir todas as outras.
Esta função possui duas sintaxes. A primeira tem o mesmo efeito do bind, registrando o evento nos elementos selecionados:
$('.classe').on('click focus', function () {
alert('evento disparado')
})
Já a segunda funciona como o delegate, registrando o evento no elemento pai e disparando nos elementos filhos filtrados por um seletor.
$('.classe-pai').on('click', 'a', function () {
alert('evento disparado')
})
Conclusão
Em resumo, antes do 1.7 use bind e delegate (este último ideal para elementos que serão criados dinamicamente ou elementos repetidos que respondem de forma semelhante a um mesmo evento). Do 1.7 pra frente, on é o cara!
[]’s