Um dos primeiros problemas que assombram os desenvolvedores iniciantes no AJAX é quando a página requisitada traz um elementos que tinham eventos definidos anteriormente…

Vamos exemplificar, vamos fazer um index.html com o seguinte código:
 HTML |  copy code |? 
01
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
02
	<head>
03
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
04
		<title>Exemplo</title>
05
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
06
		<script type="text/javascript" src="aplicacao.js"></script>
07
	</head>
08
	<body>
09
		<div id="menu">
10
			<ul>
11
				<li><a href="#" id="pagina1">Pagina 1</a></li>
12
				<li><a href="#" id="pagina2">Pagina 2</a></li>
13
			</ul>
14
		</div>
15
		<div id="conteudo">
16
			<p>Essa &eacute; uma pagina com um <a href="#" id="link">link</a></p>
17
		</div>
18
	</body>
19
</html>
Agora temos uma página html simples, vamos para o javascript, novamente usando a biblioteca JQuery.

vamos criar o arquivo aplicacao.js com o seguinte código:
 Javascript |  copy code |? 
01
$(function () {
02
	$("#pagina1").click(function () {
03
		$("#conteudo").load("conteudos.html #conteudo1");
04
		return false;
05
	});
06
	$("#pagina2").click(function () {
07
		$("#conteudo").load("conteudos.html #conteudo2");
08
		return false;
09
	});
10
	$("#link").click(function () {
11
		alert("Você clicou no link");
12
		return false;
13
	});
14
});
Vamos explicar as linhas:

Linha 1 - Define o código JQuery que será rodado no carregamento da página.

Linha 2 - Quando o elemento com id pagina1 for clicado executará uma função.

Linha 3 - Carrega o conteudo do elemento com id conteudo1 do arquivo conteudos.html (ainda vamos criar esse arquivo) para dentro do elemento com id conteudo.

Linha 4 - retorna falso, para o fluxo padrão do html para links não ser executado.

Linha 6 - Quando o elemento com id pagina2 for clicado executará uma função.

Linha 7 - Carrega o conteudo do elemento com id conteudo2 do arquivo conteudos.html (ainda vamos criar esse arquivo) para dentro do elemento com id conteudo.

Linha 8 - retorna falso, para o fluxo padrão do html para links não ser executado.

Linha 10 - Quando o elemento com id link for clicado executará uma função.

Linha 11 - Alerta o usuário que ele clicou no link.

Linha 12 - retorna falso, para o fluxo padrão do html para links não ser executado.

Criando o arquivo conteudos.html:
 HTML |  copy code |? 
01
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
02
			"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
03
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
04
	<head>
05
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
06
		<title>Exemplo</title>
07
	</head>
08
	<body>
09
		<div id="conteudo1">
10
			<p>Esse &eacute; o conteudo da primeira pagina</p>
11
			<p>Essa tambem &eacute; uma pagina com um <a href="#" id="link">link</a></p>
12
		</div>
13
		<div id="conteudo2">
14
			<p>Esse &eacute; o conteudo da segunda pagina</p>
15
			<p>Essa tambem &eacute; uma pagina com um <a href="#" id="link">link</a></p>
16
		</div>
17
	</body>
18
</html>

Pronto, está feito nosso AJAX que carrega conteudos. Mas ainda tem um problema, os links que foram carregados através do AJAX não devem estar funcionando.

Isso acontece porque a linha 10 do nosso aplicacao.js foi executada quando a página foi carregada, ou seja, o evento só foi adicionado para os elementos DOM que estavam no documento naquele momento, o que veio depois, não sofreu alteração.

Uma forma de resolver isso é executar novamente a chamada pro evento da seguinte forma:
 Javascript |  copy code |? 
01
$(function () {
02
	$("#pagina1").click(function () {
03
		$("#conteudo").load("conteudos.html #conteudo1", function(){
04
			$("#link").unbind("click");
05
			$("#link").bind("click", function () {
06
				alert("Voc&ecirc; clicou no link");
07
				return false;
08
			});
09
		});
10
		return false;
11
	});
12
	$("#pagina2").click(function () {
13
		$("#conteudo").load("conteudos.html #conteudo2", function(){
14
			$("#link").unbind("click");
15
			$("#link").bind("click", function () {
16
				alert("Voc&ecirc; clicou no link");
17
				return false;
18
			});
19
		});
20
		return false;
21
	});
22
	$("#link").click(function () {
23
		alert("Voc&ecirc; clicou no link");
24
		return false;
25
	});
26
 
27
});
Substituindo esse código no aplicacao.js resolveremos esse poblema, o que eu fiz foi setar uma função para ser executada depois que o ajax for concluído, ou seja, quando o nosso novo elemento esteja no DOM.

Eu usei unbind e depois bind para caso o link estivesse em outro lugar da pagina que não seja onde o ajax carregou o evento nao seja adicionado duas vezes, o que faria com que nossa função seja executada duas vezes resultando em 2 alerts.

Outra forma de resolver isso seria usando o plugin livequery, mas esse tutorial vou deixar para um próximo post.

Você pode ver um exemplo funcionando aqui.

Tags: , ,