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.

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.

Listagem 1. Exemplo de uso do bind()

<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>
  
Run
  • 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.
Importante: como o método bind() está marcado como deprecated na versão 3.0 da jQuery, ele provavelmente será removido em versões futuras. Para substituí-lo, a documentação oficial indica o uso do método on(), que veremos mais adiante.

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.

Listagem 2. Exemplo de uso do live()

<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>
  
Run
  • 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.

Importante: Como o método live() já foi removido da jQuery, é preciso ter cuidado ao migrar uma aplicação para versões mais recentes, uma vez que a partir da 1.9 ele não está mais disponível. Em seu lugar, atualmente, deve-se utilizar o on().

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.

Listagem 3. Exemplo de uso do delegate()

<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>
  
Run
  • Linha 10: Aqui desejamos tratar o clique dos links (tags <a>) que se encontram dentro da div de idcontainer”. 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.
Importante: Apesar de contornar alguns problemas do live(), o delegate() herda muito de seu antecessor e, por isso, não está livre dos problemas de performance, apesar de minimizá-los. Além disso, como esse método está marcado como deprecated a partir da versão 3.0, seu uso não é mais aconselhado, devendo ser substituído pelo on().

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.

Listagem 4. Exemplos de uso do on()

 $("#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");
 });
  
Run
  • 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.