AJAX – Primeiros Problemas
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:
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:
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:
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:
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.
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 é uma pagina com um <a href="#" id="link">link</a></p> |
| 17 | </div> |
| 18 | </body> |
| 19 | </html> |
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 | }); |
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 é o conteudo da primeira pagina</p> |
| 11 | <p>Essa tambem é uma pagina com um <a href="#" id="link">link</a></p> |
| 12 | </div> |
| 13 | <div id="conteudo2"> |
| 14 | <p>Esse é o conteudo da segunda pagina</p> |
| 15 | <p>Essa tambem é 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ê 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ê clicou no link"); |
| 17 | return false; |
| 18 | }); |
| 19 | }); |
| 20 | return false; |
| 21 | }); |
| 22 | $("#link").click(function () { |
| 23 | alert("Você clicou no link"); |
| 24 | return false; |
| 25 | }); |
| 26 | |
| 27 | }); |
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: AJAX, javascript, JQuery






Agora vem uma pergunta:
Tem como fazer com que as instruções do ajax permitam ou façam com que links que estão em menu em flash abram
dentro dessa div?