Motivação
A manipulação de eventos simplificada é uma das principais características da jQuery, auxiliando-a a se tornar a mais conhecida biblioteca JavaScript atualmente. Com ela, o tratamento de eventos, como o clique de um botão, a submissão de um formulário ou a digitação em um campo, pode ser feito com poucas linhas de código, utilizando uma sintaxe bastante simples.
Para isso, a biblioteca oferece diversos métodos que foram inseridos ao longo de suas versões. No entanto, havendo tantas opções para realizar a mesma tarefa, é fundamental conhecer o funcionamento de cada uma e, assim, saber por qual optar em cada cenário.
jQuery Events: Indo direto ao ponto
Nesse artigo, analisaremos os métodos bind(), live(), delegate() e on(), destacando, também, quando utilizar cada um, dependendo da versão da jQuery empregada no projeto.
Saiba mais sobre: biblioteca jQuery
Opção 1: Utilizando o bind()
Adicionado na versão 1.0 e marcado como deprecated na versão 3.0 da biblioteca, o método bind() associa uma função de tratamento (event handler) a cada um dos elementos filtrados por meio do seletor jQuery ($). Na Listagem 1 temos um exemplo de uso desse método.
<div id="container"> <a href="#">Teste 1</a><br /> <a href="#">Teste 2</a><br /> <a href="#">Teste 3</a><br /> </div> <script src="https://code.jquery.com/jquery-3.1.1.js"></script> <script> $(function(){ $("#container a").bind("click", function () { console.log($(this).text()); }); }); </script>
- Linha 7: Importamos a versão mais atual da jQuery no momento da publicação desse artigo (3.1.1);
- Linha 10: Utilizamos o bind() para associar a cada link da div container uma função para tratar seu evento de clique;
- Linha 11: Sempre que um link for clicado, seu texto será exibido no console.
O mesmo resultado poderia ser obtido com o método click() - bem como com outros referentes aos demais eventos, como blur e change - que é uma forma simplificada de associar um event handler a um elemento. Observe o código abaixo:
$("#container a").click(function () { console.log($(this).text()); });
Apesar de o bind() ser bastante flexível e permitir, inclusive, tratar vários eventos na mesma chamada, o fato de essa alternativa anexar a função de tratamento a cada um dos elementos selecionados tem algumas implicações negativas:
- O event handler não é anexado a elementos criados dinamicamente, mas apenas a aqueles que já existiam e foram selecionados no momento da chamada ao bind();
- Quanto maior o número de elementos cujos eventos são tratados, mais funções são geradas e, consequentemente, o desempenho da aplicação pode ser prejudicado.
Opção 2: Utilizando o método live()
O método live() foi introduzido na jQuery 1.3, marcado como deprecated na 1.7 e removido na 1.9. Sua sintaxe é muito semelhante ao bind(). Nesse caso, no entanto, os event handlers são adicionados não apenas aos elementos existentes, mas também a aqueles que sejam criados dinamicamente, desde que atendam ao filtro especificado no seletor. Isso ocorre porque ao invés de associar a função a cada um dos elementos, o live() anexa essa função ao elemento raiz do DOM, ou seja, o document.
Na Listagem 2 temos um exemplo de uso desse método.
<div id="container"> <a href="#">Teste 1</a><br /> <a href="#">Teste 2</a><br /> <a href="#">Teste 3</a><br /> </div> <script src="https://code.jquery.com/jquery-1.8.0.min.js"></script> <script> $(function(){ $("#container a").live("click", function () { console.log($(this).text()); $("<a href='#'>Novo link</a><br/>").appendTo("#container"); }); }); </script>
- Linha 7: Importamos a versão 1.8 da jQuery, a última em que o método live() estava disponível para uso;
- Linha 10: Usamos o live() para associar uma função ao evento de clique dos links no interior da div container;
- Linha 11: Quando clicado, o link exibirá no console seu texto;
- Linha 12: Sempre que um dos links for clicado, adicionaremos um novo link à lista. Como o live() se estende aos novos elementos, esses links adicionados dinamicamente também irão realizar os mesmos procedimentos do evento tratado.
O live() foi inserido como opção para substituir o bind() e resolvia a limitação de vincular event handlers a novos elementos. Entretanto, seu uso logo foi desencorajado, devido a alguns aspectos negativos que gerava. O principal deles dizia respeito ao desempenho, uma vez que era necessário percorrer todo o caminho do elemento selecionado até a raiz do documento para registrar um evento. Isso, em uma árvore DOM muito grande, poderia comprometer a performance da página.
Opção 3: Utilizando o delegate()
Para minimizar os problemas de desempenho gerados pelo live(), foi introduzido na versão 1.4.2 o método delegate(). Esse, ao invés de vincular o event handler ao documento, permitia selecionar um determinado elemento que seria a raiz, na hierarquia de elementos, dos itens cujo evento precisava ser tratado. Isso reduzia o “percurso” necessário para anexar a função, mas mantinha a possibilidade de novos elementos serem tratados automaticamente.
A sintaxe do delegate() pode ser verificada no exemplo apresentado na Listagem 3.
<div id="container"> <a href="#">Teste 1</a><br /> <a href="#">Teste 2</a><br /> <a href="#">Teste 3</a><br /> </div> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script> $(function(){ $("#container").delegate("a", "click", function () { console.log($(this).text()); $("<a href='#'>Novo link</a><br/>").appendTo("#container"); }); }); </script>
- Linha 10: Aqui desejamos tratar o clique dos links (tags <a>) que se encontram dentro da div de id “container”. Para isso, selecionamos a div, que é o elemento pai, e, a partir dela, chamamos o método delegate(), passando como primeiro argumento o elemento final que desejamos filtrar, ou seja, as tags <a>. Em seguida, indicamos qual evento queremos tratar (“click”) e associamos ao evento uma função;
- Linha 12: Sempre que um link for clicado, outro link será adicionado à lista. Mesmo que isso ocorra após o vínculo do event handler, os novos elementos também serão contemplados.
Opção 4: Utilizando o método on()
O método on() foi inserido na jQuery 1.7 e desde então é a opção oficialmente indicada para o tratamento de eventos. Internamente esse método utiliza as técnicas empregadas pelos seus antecessores para vincular os event handlers, porém com uma interface única. Com isso, o programador não precisa se preocupar com qual método usar, devendo optar sempre pelo on().
Há duas formas possíveis de uso do on(): vinculando a função apenas ao conjunto de elementos selecionados, como faz o bind(); ou vinculando a função à raiz do elemento em questão, semelhante ao delegate().
A Listagem 4 mostra o mesmo exemplo sendo feito das duas formas.
$("#container").on("click", "a", function () { console.log($(this).text()); $("<a href='#'>Novo link</a><br/>").appendTo("#container"); }); $("#container a").on("click", function () { console.log($(this).text()); $("<a href='#'>Novo link</a><br/>").appendTo("#container"); });
- Linha 1: Nessa chamada estamos vinculando o event handler à div container, que propagará o tratamento a todos os links em seu interior, mesmo os que forem adicionados posteriormente;
- Linha 6: Ao especificar no seletor o filtro completo apontando para os links, vinculamos uma função a cada item existente. Nesse caso, o clique dos novos links não será tratado.
É comum encontrar projetos que adotam versões anteriores da jQuery. Portanto, é fundamental conhecer os métodos que foram descontinuados ou que serão removidos em breve, a fim de garantir a estabilidade do código, mesmo com a chegada de novas versões da biblioteca.
Curso relacionado: jQuery Básico