JQuery + Ajax - JQuery não é processado

Olá, estou criando uma aplicação pra um trabalho de aula em JSP, como não me contento apenas com o que o professor passa sobre JSP decidi criar a página com Ajax e JQuery, estou pesquisando bastante pela internet, e ja consegui construir algumas coisas legais.

Quando fui tentar processar um código JQuery dentro de uma página que foi carregada pelo AJAX, este código não funciona, se eu tento acessar a página diretamente sem ir pelo fluxo ( clicar no menu e tal que é onde o ajax faz a sua parte ) o código JQuery funciona, meu código está assim:

showFoto.js:
JQuery:

 $(document).ready(function() {
    	$("a#imgtbg").fancybox({
			'transitionIn'	: 'elastic',
			'transitionOut'	: 'elastic'
		});
 });

Página estática:

<div class="menuLateral">
<a onclick="loadPage('gratificacoes.jsp');">Gratificações</a><br>
</div>

Página carregada pelo ajax:

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel=stylesheet href="resources/css/menu.css" type="text/css">
<link rel="stylesheet" href="resources/css/topStyle.css" type="text/css" />
<link rel="stylesheet" href="resources/css/dock.css" type="text/css" />

<link rel="stylesheet" type="text/css" href="fancybox/jquery.fancybox-1.3.4.css" media="screen" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" language="javascript"></script>
<script type="text/javascript" src="fancybox/jquery.fancybox-1.3.4.pack.js"></script>
<script type="text/javascript" src="resources/js/showPhoto.js"></script>
</head>
<body>
<jsp:include page="tgo.jsp"></jsp:include>
</body>
</html>

Página tgo.jsp do include

head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel=stylesheet href="resources/css/menu.css" type="text/css">
<link rel="stylesheet" href="resources/css/topStyle.css" type="text/css" />
<link rel="stylesheet" href="resources/css/dock.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="fancybox/jquery.fancybox-1.3.4.css" media="screen" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" language="javascript"></script>
<script type="text/javascript" src="fancybox/jquery.fancybox-1.3.4.pack.js"></script>
<script type="text/javascript" src="resources/js/showPhoto.js"></script>

</head>
<body>
<div id="gallery">
<a id="imgtbg" href="resources/images/tgop1.png"><img src="resources/images/tgop1.png" width="200" height="150" alt="" /></a>
</div>

Agradeço toda e qualquer ajuda.

Vamos ao primeiro problema:
Nunca coloque código JS nos elementos, ou seja:

Isso é feio…
Algo mais bonito:

&lt;!-- // No HTML fica assim: --&gt;
&lt;a id="gratificacoes" &gt;Gratificações&lt;/a&gt; &lt;!--// sempre precisa colocar o href no &lt;a&gt; --&gt; 

// Arquivo .js separado
$('#gratificacoes').on('click', function(){
   loadPage('gratificacoes.jsp');
});

Agora vamos ao segundo problema… Quando você carrega com ajax, a página carregada vai fazer parte do DOM da página atual, ou seja, a página já tem o head…

Para resolver isso, essa página deveria ser colocada assim:

&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" language="javascript"&gt;&lt;/script&gt;  
&lt;script type="text/javascript" src="fancybox/jquery.fancybox-1.3.4.pack.js"&gt;&lt;/script&gt;  
&lt;script type="text/javascript" src="resources/js/showPhoto.js"&gt;&lt;/script&gt;    

&lt;div id="gallery"&gt;  
&lt;a id="imgtbg" href="resources/images/tgop1.png"&gt;&lt;img src="resources/images/tgop1.png" width="200" height="150" alt="" /&gt;&lt;/a&gt; 
&lt;/div&gt;  

[quote=Rafael Guerreiro]Vamos ao primeiro problema:
Nunca coloque código JS nos elementos, ou seja:

Isso é feio…
Algo mais bonito:

&lt;!-- // No HTML fica assim: --&gt;
&lt;a id="gratificacoes" &gt;Gratificações&lt;/a&gt; &lt;!--// sempre precisa colocar o href no &lt;a&gt; --&gt; 

// Arquivo .js separado
$('#gratificacoes').on('click', function(){
   loadPage('gratificacoes.jsp');
});

Agora vamos ao segundo problema… Quando você carrega com ajax, a página carregada vai fazer parte do DOM da página atual, ou seja, a página já tem o head…

Para resolver isso, essa página deveria ser colocada assim:

[code]
<script src=“https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js” language=“javascript”></script>
<script type=“text/javascript” src=“fancybox/jquery.fancybox-1.3.4.pack.js”></script>
<script type=“text/javascript” src=“resources/js/showPhoto.js”></script>

<div id=“gallery”>
<a id=“imgtbg” href=“resources/images/tgop1.png”><img src=“resources/images/tgop1.png” width=“200” height=“150” alt="" /></a>
</div>

[/code][/quote]

Muito obrigado, nunca utilizei java script e não tive ninguém que me ensinasse, obrigado pelas dicas, vou tentar aqui e ja coloco uma resposta, você diz que não estava funcionando porque o head estava repetido?

Att,

Olá fiz os testes aqui e não funcionou ):, provavelmente por causa das outras paginas que não deixei explicita na minha explicaçao, vou explicar melhor para talvez descobrir se há mais alguma coisa implicando neste problema.

Primeiramente tenho uma página JSP dentro da minha página principal, essa minha pagina JSP tem 4 DIVS dividdas em dock panels e dentro de cada dock deste eu carrego uma página jsp com a função include:

dock TOP:
<jsp:include page=“top.jsp”></jsp:include>
dock MENU
<jsp:include page=“menuLateral.jsp”></jsp:include>
dock FEED:
<jsp:include page=“feed.jsp”></jsp:include>
dock RIGHT:
<jsp:include page=“menuRight.jsp”></jsp:include>
dock BOTTOM

Os links do menuLateral.jsp irão via AJAX inserir um HTML na pagina feed.jsp.

Então no menuLateral tenho meus links, e clicando em um deles, eu insiro um HTML na pagina feed.jsp.

então o fluxo é:
Abrir pagina principal < carrega todos os includes >
Clica no link “Gratificacoes” no menuLateral. ao clicar no menu ele irá chamar o AJAX que passará para ele um HTML.
Este html é este:

[code]

[/code]

Então ele gospe o html acima e insere dentro da pagina feed.jsp após clicar no menu gratificações.

a página tgo.jsp está assim:

[code]

[/code]

minha estrutura de pastasestá assim:

WebContent
gratificacoes.jsp
top.jsp
tgo.jsp
feed.jsp
rodape.jsp
menuLateral.jsp
+resources
+css
- todos os css
+images
- todas as imagens
+js
-ajax.js
-instrucoes.js
-showPhoto.js
+fancybox
- todas as bibliotecas imagens e css necessários para o funcionamento do fancyboxs
+WEB-INF
+META-INF

Tirei todos os heads das paginas que estão dentro do fluxo como você me instruiu, e organizei os .js como descrito por você.

O que eu posso ter feito de errado?

Att,

Esse jeito de trabalhar com include de JSP é um pouco feio…

Mas, você precisa lembrar de que JSP na verdade é um HTML um pouco dinâmico… Ou seja, você tem que tratá-lo como um HTML:

&lt;!-- // CADE O &lt;head&gt; e o &lt;body&gt;???? --&gt;
&lt;html&gt;&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
dock TOP: 
&lt;jsp:include page="top.jsp"&gt;&lt;/jsp:include&gt; 
dock MENU 
&lt;jsp:include page="menuLateral.jsp"&gt;&lt;/jsp:include&gt; 
dock FEED: 
&lt;jsp:include page="feed.jsp"&gt;&lt;/jsp:include&gt; 
dock RIGHT: 
&lt;jsp:include page="menuRight.jsp"&gt;&lt;/jsp:include&gt; 
dock BOTTOM
&lt;/body&gt;
&lt;/html&gt;

[quote=Rafael Guerreiro]Esse jeito de trabalhar com include de JSP é um pouco feio…

Mas, você precisa lembrar de que JSP na verdade é um HTML um pouco dinâmico… Ou seja, você tem que tratá-lo como um HTML:

&lt;!-- // CADE O &lt;head&gt; e o &lt;body&gt;???? --&gt; &lt;html&gt;&lt;head&gt;&lt;/head&gt; &lt;body&gt; dock TOP: &lt;jsp:include page="top.jsp"&gt;&lt;/jsp:include&gt; dock MENU &lt;jsp:include page="menuLateral.jsp"&gt;&lt;/jsp:include&gt; dock FEED: &lt;jsp:include page="feed.jsp"&gt;&lt;/jsp:include&gt; dock RIGHT: &lt;jsp:include page="menuRight.jsp"&gt;&lt;/jsp:include&gt; dock BOTTOM &lt;/body&gt; &lt;/html&gt; [/quote]

Imaginei que você fosse dizer isso, mas o que eu escrevi foi só uma representação OK? o código verdadeiro não está assim, só escrevi para melhor entendimento.

No momento não tenho o código para lhe enviar, mas esta correto e esta funcionando pois se não, minhas páginas AJAX não estavam funcionando o que não é o caso.

O caso mesmo é porque o JQuery não está funcionando quando a página é chamada por uma requisição AJAX

Momento vivendo e aprendendo: Qual seria o jeito bonito de se trabalhar com JSP?

Quando você conseguir os arquivos, coloque-os inteiros aqui, talvez alguma coisa esteja passando batido.

Quanto às boas práticas para o JSP, deve pensar nas boas práticas para se trabalhar com HTML…

Para isso, existe um post bom sobre isso:
http://blog.caelum.com.br/por-uma-web-mais-rapida-26-tecnicas-de-otimizacao-de-sites/

Lógico que em desenvolvimento, não vamos comprimir os CSS e JS, pois precisam de manutenção, então, deixe isso para a implantação em produção.
Salve sempre a versão descomprimida para poder continuar a dar manutenção.

Outra coisa, cuidado com Javascript, por exemplo, quando você carrega uma página com ajax que contém um arquivo js, o jQuery vai executar esse JS quando você o colocar na página, e isso é pouco performático.
Por isso, é de boa prática você usar o ‘live’ para eventos. O ‘live’ diz o seguinte: para todos os objetos que tiverem esse seletor que estão e serão criados vão executar esse callback nesse evento.
Fica assim com jQuery:

$(document).on('click', '.clickable', function(){
      alert('Clicou!!');
});

Ou seja, todo elemento criado DENTRO de document que contém a classe ‘clickable’, vai apresentar um alert quando fizermos o click.

Lógico que isso funciona para os elementos criados dentro de uma determinada div…

A dica aqui é o seguinte: coloque os eventos no live e os carregue e execute antes. Depois, quando o Ajax for acionado, os elementos que estão lá dentro já têm o evento carregado.

[quote=Rafael Guerreiro]Quando você conseguir os arquivos, coloque-os inteiros aqui, talvez alguma coisa esteja passando batido.

Quanto às boas práticas para o JSP, deve pensar nas boas práticas para se trabalhar com HTML…

Para isso, existe um post bom sobre isso:
http://blog.caelum.com.br/por-uma-web-mais-rapida-26-tecnicas-de-otimizacao-de-sites/

Lógico que em desenvolvimento, não vamos comprimir os CSS e JS, pois precisam de manutenção, então, deixe isso para a implantação em produção.
Salve sempre a versão descomprimida para poder continuar a dar manutenção.

Outra coisa, cuidado com Javascript, por exemplo, quando você carrega uma página com ajax que contém um arquivo js, o jQuery vai executar esse JS quando você o colocar na página, e isso é pouco performático.
Por isso, é de boa prática você usar o ‘live’ para eventos. O ‘live’ diz o seguinte: para todos os objetos que tiverem esse seletor que estão e serão criados vão executar esse callback nesse evento.
Fica assim com jQuery:

$(document).on('click', '.clickable', function(){
      alert('Clicou!!');
});

Ou seja, todo elemento criado DENTRO de document que contém a classe ‘clickable’, vai apresentar um alert quando fizermos o click.

Lógico que isso funciona para os elementos criados dentro de uma determinada div…

A dica aqui é o seguinte: coloque os eventos no live e os carregue e execute antes. Depois, quando o Ajax for acionado, os elementos que estão lá dentro já têm o evento carregado.[/quote]

Gostaria de agradecer pelo link vou ler com bastante afinco e também pelas explicações, acredito ter entendido exatamente o que você quis dizer. Mas gostaria de consolidar,

Eu devo criar uma instrução igual a esta que você criou porém eu posso escolher a DIV que executará aquela instrução e em qual evento isto será feito, exemplo: click, mouseout, mouseup, etc?

Para mim escolher qual DIV vai executar este comando, qual o campo que devo alterar o '.clickable'? assim:

$(document).on(‘click’, ‘.gratificacoes’, function(){
alert(‘Clicou!!’);
});
Ou vai ficar de outra forma (sintaxe) ?

Eu ja tinha pesquisado e encontrado este live em alguns outros lugares, porém era algo assim:

$(document).on(live((‘click’, ‘.gratificacoes’, function(){
alert(‘Clicou!!’));
});

Na hora da digitação você não esqueceu de alguma “tag” de nome live? ou live é apenas o conceito da instrução?

Como é um JavaScript, eu sempre preciso colocar entre <script></script> certo?

Esta função, eu devo colocar na página principal, ou não há limitações quanto a isso? digo… posso coloca-la diretamente na pagina tgo.jsp que será carregada pelo AJAX?
(Estou perguntando isso pela sua dica: " coloque os eventos no live e os carregue e execute antes " antes que você diz é antes do carregamento de todas as páginas ou na hora
que estou “startando” o servidor esses eventos são carregados quando existe uma instrução live?

Vamos lá!

Não esqueci de nenhum nome live… Esse nome era usado nas versões anteriores do jQuery e eles juntaram ela e o bind em um único método, o on…
Segue Docs:
Live (Depreciado e removido)
http://api.jquery.com/live/
Bind
http://api.jquery.com/bind/
On (SUBSTITUI ambos acima, só mudando a forma de usar)
http://api.jquery.com/on/

As diferenças entre o bind e o live:
Bind: Afeta todos os elementos que tiverem aquele seletor mas apenas uma vez, os elementos futuros não serão afetados.
Live: Afeta todos os elementos que tiverem aquele seletor E os futuros que tiverem o mesmo seletor.

Como é javascript, você precisa sim colocar entre as tags script. Mas isso não é uma boa prática.
A boa prática é você criar um arquivo com a extensão .js separado e incluir ele usando a tag script. Assim, o browser faz cache desse script :wink:

Quando eu digo execute antes de carregar, me refiro ao seguinte:
Se você usar o live (escrito na forma do on) na primeira página, todos os elementos carregados DEPOIS via AJAX também vão ter o evento. Ou seja, não carregue código JS no ajax, somente o html… Deixe o código js na página principal.

[quote=Rafael Guerreiro]Vamos lá!

Não esqueci de nenhum nome live… Esse nome era usado nas versões anteriores do jQuery e eles juntaram ela e o bind em um único método, o on…
Segue Docs:
Live (Depreciado e removido)
http://api.jquery.com/live/
Bind
http://api.jquery.com/bind/
On (SUBSTITUI ambos acima, só mudando a forma de usar)
http://api.jquery.com/on/

As diferenças entre o bind e o live:
Bind: Afeta todos os elementos que tiverem aquele seletor mas apenas uma vez, os elementos futuros não serão afetados.
Live: Afeta todos os elementos que tiverem aquele seletor E os futuros que tiverem o mesmo seletor.

Como é javascript, você precisa sim colocar entre as tags script. Mas isso não é uma boa prática.
A boa prática é você criar um arquivo com a extensão .js separado e incluir ele usando a tag script. Assim, o browser faz cache desse script :wink:

Quando eu digo execute antes de carregar, me refiro ao seguinte:
Se você usar o live (escrito na forma do on) na primeira página, todos os elementos carregados DEPOIS via AJAX também vão ter o evento. Ou seja, não carregue código JS no ajax, somente o html… Deixe o código js na página principal.[/quote]

Olá pesquisei bastante, até sentei com meu professor ontem e ele tentou me ajudar mas não conseguimos resolver, o meu código está assim:

$( document ).ready(function() {
$("#gra").on(“click”, function(event){
alert(‘teste’);
});
});

porém no Console Firebug ele da um erro na console assim $(…) not is a function, e este erro ocorre na linha do .on(“click”)

a id “gra” é o id de um link, você tem idéia do que pode ser? eu e meu professor pesquisamos na net e encontramos algo sobre conflito de “$”, que informava para utilizarmos
jQuery(…) ao invés de $(…), após fazer isso ele acusa o mesmo erro dizendo que jQuery(…) not is a function

Há algum outro teste que posso fazer?

Faltou você colocar o js do jQuery no seu projeto…

Lembre-se de que o HTML, JS e CSS são INTERPRETADOS e não compilados.

O que significa: Você precisa importar o js do jQuery antes de usar qualquer função dele…

Veja se não é esse o problema…

[quote=Rafael Guerreiro]Faltou você colocar o js do jQuery no seu projeto…

Lembre-se de que o HTML, JS e CSS são INTERPRETADOS e não compilados.

O que significa: Você precisa importar o js do jQuery antes de usar qualquer função dele…

Veja se não é esse o problema…[/quote]

Então este codígo que passei pra você está dentro do showPhoto.js um arquivo separado.

na minha página HTML, o JQuery é o primeiro a ser carregado, logo depois vem o showPhoto.js, isto tudo na página que eu quero carregar este evento, mas também, este código esta sendo repetido em outras páginas ( a importação do script ), ele pode estar se perdendo nesse caso? ele vai considerar sempre a primeira importação?

Ele vai sempre sobrescrever as funções…

Faça um teste:
Crie uma function chamada fazAlgo e mande ela dar um alert(‘1’);

Depois, logo abaixo, crie a mesma function, só que mude o alert para alert(‘2’);

Execute a function e veja qual será executado…

Para que eu consiga te ajudar melhor, seria interessante você postar todos os seus códigos envolvidos nessa tela…

[quote=Rafael Guerreiro]Ele vai sempre sobrescrever as funções…

Faça um teste:
Crie uma function chamada fazAlgo e mande ela dar um alert(‘1’);

Depois, logo abaixo, crie a mesma function, só que mude o alert para alert(‘2’);

Execute a function e veja qual será executado…

Para que eu consiga te ajudar melhor, seria interessante você postar todos os seus códigos envolvidos nessa tela…[/quote]

farei isso assim que chegar em casa, eu posso te enviar por e-mail o projeto .war?

Pode colocar ele aqui como anexo…

Na hora de gerar o .war, mande o eclipse colocar o código java…

[quote=Rafael Guerreiro]Pode colocar ele aqui como anexo…

Na hora de gerar o .war, mande o eclipse colocar o código java…[/quote]

Olá, enviei o projeto via inbox, mas podemos continuar conversando por aqui!

[quote=LVentura][quote=Rafael Guerreiro]Pode colocar ele aqui como anexo…

Na hora de gerar o .war, mande o eclipse colocar o código java…[/quote]

Olá, enviei o projeto via inbox, mas podemos continuar conversando por aqui![/quote]

Olá, não querendo ser chato ou cobrar alguma coisa mas creio que tenha esquecido deste tópico, estou respondendo para ver se você lembra ):

Vamos lá!

Olhei o seu projeto, primeiro, nunca faça código java em uma JSP. Os códigos devem ficar separados. Depois você vai ver como que deve fazer isso. Mas tenha em mente que a manutenção desse seu sistema vai ser muito custosa se continuar dessa forma.

Segundo, quando eu disse que você só pode ter um <html><head></head> na sua página vc deveria olhar TODAS as outras páginas.

O include te sacaneou aqui, quando você faz o include, ele pega todo o conteúdo e coloca na sua página atual. Ou seja, isso:

&lt;div class="dockTop"&gt;
&lt;jsp:include page="top.jsp"&gt;&lt;/jsp:include&gt;
&lt;/div&gt;

É igual a isso:

&lt;div class="dockTop"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;
&lt;link rel="stylesheet" href="resources/css/topStyle.css" type="text/css" /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=divTop&gt;
&lt;div class=imageOwl&gt;<img   >&lt;/div&gt;
&lt;div class=nomeUser&gt;&lt;/div&gt;
&lt;div class=botaoSair&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;

Não pode fazer isso… Então todas as telas que você usar no include devem ficar iguais à tgo.jsp.
Tome cuidado para não repetir o CSS e JS incluídos pois eles vão ficar duplicados.

[quote=Rafael Guerreiro]Vamos lá!

Olhei o seu projeto, primeiro, nunca faça código java em uma JSP. Os códigos devem ficar separados. Depois você vai ver como que deve fazer isso. Mas tenha em mente que a manutenção desse seu sistema vai ser muito custosa se continuar dessa forma.

Segundo, quando eu disse que você só pode ter um <html><head></head> na sua página vc deveria olhar TODAS as outras páginas.

O include te sacaneou aqui, quando você faz o include, ele pega todo o conteúdo e coloca na sua página atual. Ou seja, isso:

&lt;div class="dockTop"&gt;
&lt;jsp:include page="top.jsp"&gt;&lt;/jsp:include&gt;
&lt;/div&gt;

É igual a isso:

&lt;div class="dockTop"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;
&lt;link rel="stylesheet" href="resources/css/topStyle.css" type="text/css" /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=divTop&gt;
&lt;div class=imageOwl&gt;<img   >&lt;/div&gt;
&lt;div class=nomeUser&gt;&lt;/div&gt;
&lt;div class=botaoSair&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;

Não pode fazer isso… Então todas as telas que você usar no include devem ficar iguais à tgo.jsp.
Tome cuidado para não repetir o CSS e JS incluídos pois eles vão ficar duplicados.[/quote]

Olá, efetuei todas as modificações, e coloquei todos os CSS e JS apenas na pagina principal.

Também concordo que fica horrível colocar os códigos java diretamente na JSP, como posso fazer isso em um arquivo separado?

é possível eu chamar um Servlet sem utilizar um Form?? por exemplo para inserir um valor no banco de dados quando eu clicar em um determinado botão que não seja um submit?

Use servlet para executar o código java.

É possível sim, mas o ideal é que você use o form para isso…