O seletor jquery não funciona depois do ajax com o click() e outros eventos – use o live()!

O assunto é extremamente simples, mesmo assim é um dos mais procurados e não há muita facilidade de se encontrar no google com palavras chave comuns às perguntas que são feitas.

Sempre aparecem perguntas na lista do Google Groups “jQuery Brasil” sobre exatamente a mesma resposta:

  • “O evento click() para de funcionar depois de criar elementos com ajax”
  • “Seletor do jQuery para elementos criados com ajax”
  • Meu site para depois da resposta ajax
  • O jQuery não funciona direito com o ajax, só funciona antes de usa-lo

A resposta e a solução são simples:

Usem o maldito live!


Por exemplo, onde tinhamos:

$('elemento').click(function() {
   /* sua mágica em particular */
});

Podemos passar a usar:

$('elemento').live('click', function() {
   /* sua mágica em particular */
});

A diferença é simples: o método click() vai ser aplicado apenas aos elementos passados no momento em que ele foi chamado. Já com o uso do live() nós vamos ter uma verificação para o evento com esse ocorrer a qualquer elemento que combine com aquele passado no seletor, a qualquer momento em que ocorra o evento!

O elemento pode ser qualquer coisa e o evento pode ser qualquer um abordado pelo jQuery (desde a versão 1.4+), vamos supor que aqui queremos trabalhar com todos os campos input de texto que, ao ganharem foco (evento focus), tenham seu texto selecionado (método select() do jQuery).

Primeiramente podemos selecionar o input de texto de duas formas: input[type=text] ou input:text. Vamos usar o segundo caso, que é ligeiramente mais curto. Vamos ao exemplo:

$('input:text').live('focus',function() {
   $(this).select();
});

Bem simples, não? Assim qualquer input de texto no documento ao receber foco vai ter seu texto selecionado. Mesmo que ele venha existir apenas depois do carregamento da página, sendo criado em um evento dinâmico ou por uma requisição ajax.

Quer testar? Expiremente:

$('a#criarinput').live('click', function(e) {
   e.preventDefault();
   var $localPraIncluir = $(this).parent(); // usei o $ porque costumo o fazer quando é pra identificar um objeto/coleção/elemento jQuery
   $('<input type="text" value="ola mundo de novo e de novo" />').appendTo($localPraIncluir);
   $localPraIncluir.find('input:text').last().focus();
});

Aproveitei e fiz umas pequenas adições interessantes no código.

Quer testar? expiremente o jsbin usando o código que criamos: http://jsbin.com/emovi3/6

Quer ver o código completo utilizado no jsbin?

HTML:

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
  article, aside, figure, footer, header, hgroup,
  menu, nav, section { display: block; }
</style>
</head>
<body>
  <header>
    <h1>Clica aí!</h1>
  </header>
  <section>
    <a href="#" id="criarinput">Bem aqui!</a>
  </section>
</body>
</html>

Javascript:

jQuery(function($) {
  $('input:text').live('focus',function() {
    $(this).select();
  });
 
  $('a#criarinput').live('click', function(e) {
    e.preventDefault();
    var $localPraIncluir = $(this).parent();
    /* usei o $ acima porque costumo o fazer quando
     * é pra identificar um objeto/coleção/elemento
     * jQuery
     */
    $('<input type="text" value="ola mundo de novo e de novo" />').appendTo($localPraIncluir);
    $localPraIncluir.find('input:text').last().focus();
  });
});

2 Respostas para “O seletor jquery não funciona depois do ajax com o click() e outros eventos – use o live()!”

  1. Suissa disse:

    PERFEITO cara!

    Cansei de responder live() la!

  2. Leonardo Balter disse:

    Está impressionante mesmo como o artigo tem dado retorno, sempre aparecendo pessoas com esse tipo de dúvida.

    Foi bacana ter sacado esse post sobre o live()

Deixar uma resposta


Performance Optimization WordPress Plugins by W3 EDGE