Seções iMasters
Ajax + JQuery

Botões de voltar e avançar funcionando com JQuery

Olá a todos! Hoje abordarei uma forma de contornar um problema comum a quem usa AJAX no site.

Sabemos que fazer requisições assíncronas ao servidor é muito bom, mas às vezes tem seus custos. Uma das coisas que acontecem e muitas vezes atrapalham o usuário que não está acostumado é a perda do histórico de navegação dos botões de voltar avançar do navegador.

A forma de contornar isso, descrita abaixo, é usando o plugin do JQuery jquery.history

Primeiramente, precisamos adicionar a biblioteca JQuery na lista de scripts:

<script type="text/javascript" src="jquery.js"></script>

Depois disso temos que adicionar o plugin jquery.history

<script type="text/javascript" src="jquery.history.js"></script>

Agora vamos cadastrar a função que tem o poder de adicionar histórico ao browser:

<script type="text/javascript">
	function pageload(hash) {
		
		if(hash) {
			
			$("#load").load(hash + ".html");
		} else {
			$("#load").empty();
		}
	}
	
	$(document).ready(function(){
		
		$.historyInit(pageload);
		
		$("a[@rel=´imasters´]").click(function(){
			var hash = this.href;
			hash = hash.replace(/^.*#/, ´´);
			$.historyLoad(hash);
			return false;
		});
	});
</script>

A função $.historyInit(pageload) permite que a função que está dentro do parâmetro, ou seja, pageLoad, adicione os históricos de navegação, lembrando que a função pageLoad poderá ser modificada de acordo com as necessidades do projeto – pois ela está bem simples no exemplo – e está apenas carregando páginas html de acordo com o parâmetro, mas serve para o entendimento do artigo, que é deixar funcionando os botões de voltar e avançar do navegador.

Se colocarmos o seguinte código html no conteúdo da página:

  <a href="#1" rel="imasters">página 1</a><br />
  <a href="#2" rel="imasters">página 2</a><br />
  <a href="#3" rel="imasters">página 3</a><br />
	
  <hr />
  Conteúdo:<br />

  <div id="load"></div>

Poderemos ver que o site funcionará como se estivéssemos mudando de página a cada link, mas estamos na verdade mudando apenas o conteúdo da div <div id="load"></div> , que é exatamente o que queremos.

Pronto! Agora podemos utilizar o AJAX na página como quisermos e o histórico de navegação será automaticamente adicionado ao navegador.

Para ver o exemplo acima funcionando acessem o link http://www.alantiel.com/~file/jqueryhistory

Mensagem do anunciante:

Receba consultoria especializada em WordPress com os melhores profissionais do mercado. Conheça o Apiki WP Consultoria.

Comente também

61 Comentários

Diego Fleury

Seu código não vai funcionar. Jquery está procurando por a[@rel=´history´] mas nos elementos está rel=”imasters”… flw

Alantiel Freire Marins

Obrigado pela observação Diego,

Vou pedir a edição.
Para quem for fazer, enquanto não estiver corrijido, troquem o cogido:
$(“a[@rel=´history´]“)
por
$(“a[@rel=´imasters´]“)

Obrigado pela observação
abs

    fabiophp@ymail.com

    Agora me explica uma coisa, o código está atualizando a url perfeitamente, porém como é possível um site atualizar o conteudo via ajax e ainda assim o botao do histórico voltar e avançar funcionar perfeitamente como se a pagina estivesse sendo toda atualizada
    tipo assim : denizardo12.wix.com/dze-serralheria-

    Falow

Alantiel Freire Marins

Olá,
no arquivo de exemplo está com a correção
http://www.alantiel.com/~file/jqueryhistory/
agora só falta no artigo…
Qualquer coisa mandem e-mail.

Alantiel Freire Marins

Correção OK!

Raphael França Marques

OPA, muito obrigado velho, tava procurando isso a muito tempo e num achava explicação pra isso… Todo mundo só ‘tinha ouvido falar’… Anyways, testarei hoje e qualquer dúvida, posto aqui.

Alantiel Freire Marins

Opa,
Que bom que foi útil para você… qualquer coisa posta ai!

Alantiel Freire Marins

Coloquei um link para baixar o exemplo zipado, para ficar mais fácil para quem for usar…
até a próxima!

Eduardo Moreno

Estou desenvolvendo a seguinte página http://www.pangeazoopet.com.br e o menu é composto de um link PHP com determinados parametros. Ex. href=”#pagina.php?par=1″

No ie7, FF2.0 e 3.0 tá tudo OK. Porém no ie6 ele simplesmente exclui o “?par=1″, ficando apenas “#pagina.php” no hash.

Há alguma solução para esse problema?

    Diego Santana das neves

    olá estou com o mesmo problema, teve alguma resposta em 2 anos rsrsrsrs

Alantiel Freire Marins

Olá Eduardo,
bom exemplo esse que trouxe para integrar com o artigo, me passe o codigo da página PHP e js que vc está usando por e-mail: nome@nome.com (troque nome por alantiel, apenas escrevi assim para impedir robôs de span)
Eu vejo como consertar e te respondo, depois posto aqui a solução js para quem tiver o mesmo problema.
(a solução é passar por parametros o que é dinamico, ou seja, os parâmetros da querystring)

Paulo Pederro

Alantiel..Seu codigo é joia..mais to com um problema.. usei $(‘#load’).load(“primeira_pagina.html”); que carrega a pagina no load..blz..essa pagina tem outros links pra outras paginas internas…eu quero que elas abram na mesma div load…só que no IE não funciona, no Firefox ta blz..qq pode ser?

Alantiel Freire Marins

Paulo, beleza ai cara?
Então, eu já tive uns problemas com IE (normal rs), talvez eu possa te ajudar. se quiser me mandar um e-mail com o seu codigo, ou parte dele, eu dou uma analizada e te respondo o que pode ser.
T+

Paulo Pederro

Cara Obrigado por me ajudar!! espero resolver isso !! Ja to mandando..abraço

Junior Cwb

Consegui tirar o # da chamada ajax para funcionar normalmente no CodeIgniter + jquery.history, mas ele ainda fica aparecendo na url da barra de endereços. É questão de estética, mas depois de tirar o index.php para deixar a url mais amigável, esse # não tá me agradando ali.

Junior Cwb

Em tempo: Alantiel, teus artigos sobre o CodeIgniter estão show de bola. Com Jquery + Ajax então tá arrebentando. Valeu, parabéns!

    Alantiel Freire Marins

    @Junior,
    Obrigado pela leitura e comentários positivos!
    Então, uma forma que eu penso que funcione retirar o # da url seria algum location.replace de tudo após o # (junto com o #), mas ai teria que guardar essa string em alguma variável e modificar o plugin para carregar a partir dessa string e não mais da url… Essa solução acabei de pensar, mas nem testei ainda, se quiser tentar fazer ai, depois avisa pra gente, de qualquer forma, quando tiver algum tempinho sobrando vou tentar fazer isso ai eu posto aqui o resultado.
    Até mais

Junior Cwb

Prá funcionar no CI foi tranquilo (“http://www.blog.petesaia.com/2009/10/codeigniter-jquery-ajax-pagination/”), mas tirar o # da barra de endereços acho que não dá mesmo, nesse modelo.
O carregamento do history está sendo feito alterando o objeto location, mas se este não recebe um # irá redirecionar (requisição síncrona) para o novo endereço.
Assim, se fizer hash = ‘teste’ e location.href += ['/'+] hash ele redirecionará para url_atual/teste e não achei meio de cancelar o redirecionamento. Desconheço que haja tratador para o evento e via unload parece-me impossível.
E se fizer location.hash = hash (hash = ‘teste’) o navegador adiciona ‘#teste’ na url, ou seja, o # entra de um jeito ou de outro.
Acho que só se houver outro meio de incrementar history, que não via location, mas pelo que vi a manipulação de history é vedada e até a sua leitura requer privilégios.
Abços.

Alex Araujo

Amigos tenho um menu em flash que chama uma função simples para abrir as páginas

function abrirPag( url, conteudo){
$(‘#conteudo’).load(url);
}

Os botões flash estão chamando a função e enviando a url correspondente. Como faço para implementar esta função para este caso Grato

Olá Alantiel primeiramente quero parabeniza-lo pela excelente solução, e gostaria de solicitar uma ajuda que para resolver o problema de enviar parametros php, por exemplo tenho um formulário de edição e uma tabela de dados nessa tabela eu tenho

Editar“;

o que eu preciso é receber este id no formulário de edição mas ele mostra o erro

mysql_fetch_assoc(): supplied argument is not a valid MySQL

Justamente pelo fato do id não estar sendo enviado

Como poderia resolver este pequeno probleminha agradeço muito sua ajuda

Grato

Alex Araujo

Alguém teria uma luz para o problema com flash

    Alantiel Freire Marins

    Alex, sobre essa dúvida acho que seria da mesma forma que você fez para chamar o javascript que já está funcionando… não sei muito bem qual é a dúvida nesse caso.

Alex Araujo

A dúvida é a seguinte o botão flash chama a função

function abrirPag( url, conteudo){
$(‘#conteudo’).load(url);
}

até ai tudo bem porém eu não sei como faço para o jquery saber que cliquei em outro botão (flash) e abri uma nova página. No caso de sites feitos em css é facil pois você pega o evento click dos elementos “a” (links) no flash eu não sei como fazer.

    Alantiel Freire Marins

    Ah… agora deu pra entender…
    Não sei se dá pra simular exatamente o click event pelo flash, mas uma forma que eu pensei agora pra contornar isso seria, ter o mesmo menu que você tem no flash em html (mas oculto na página) e no flash fazer um click nos botões html… tipo:
    function abrirPag( url, conteudo){
    $(‘#botalCorrepondente’).click();
    Ai ficaria da forma convencional.

Alex Araujo

Não consegui uma solução para o meu caso. Não gostaria de fazer uma gambiarra.

Alex Araujo

Modifiquei a função e coloquei tudo em um arquivo:

function abrirPag( url, id, conteudo){

$(‘#conteudo’).load(url);

function pageload(hash) {

if(hash) {

$(“#conteudo”).load(hash);

} else {
$(“#conteudo”).empty();
}
}
$(document).ready(function(){

$.historyInit(pageload);
var hash = id;
hash = hash.replace(“#”, ” “);
$.historyLoad(hash);
return false;

});
}

Funcionou porém não consegui fazer o replace da tralha ‘#’ e ficou uma dúvida. Se a pessoa tiver navegando pelo site e em determinada página ela der um refresh o site recarrega e retorna para a primeira página(principal), tem como resolver isto ? Grato

    Alantiel Freire Marins

    Para que o F5 não retorne para a raiz o hash deveria estar na url… pelo flash você consegue mudar o parâmetro da url?

Alex Araujo

Fiz as alterações mas não consegui resolver.

A função ficou assim :

function abrirPag( url, conteudo){

function pageload(hash) {

if(hash) {

$(‘#conteudo’).load(hash + “.html”);

} else {
$(‘#conteudo’).empty();
}
}
$(document).ready(function(){

$.historyInit(pageload);
var hash = url;
$.historyLoad(hash.replace(/^.*#/, ”));
return false;

});
}

No flash ficou assim :

on (release)
{

getURL(‘javascript:abrirPag(“#home”);’);
}

Sou iniciante e ainda tenho alguma dificuldades. Obrigado

Thiago Ferri

Estou com um problema pessoal, o plugin funciona normalmente, porem se eu coloco um EMBED tipo video do youtube, ai tem um problemao, ele muda o TITLE da pagina inteiro, por exemplo se eu abrir uma pagina com nome HASH principal, ele tira o title da pagina e fica #principal no lugar.

Se tive por exemplo 2 embed, vai fica #principal #principal.
Não sei como resovler isso. Alguem tem idéia?

Pra vocês verem o que acontece acessem: http://www.dentrodofato.com.br

Aguardo respostas e obrigado.

Paulo Rafael Silva

Parabéns pelo post, estava procurando isso há tempos.
Estou usando em um site que eu estou fazendo, e está funcionando perfeitamente.
Até o no IE 6 funciona. Valeu.

Cara, o código só está funcionando quando as páginas estão na extensão HTML.

Já alterei a linha: $(“#load”).load(hash + “.html”);

Para: $(“#load”).load(hash + “.php”);

Porém não funcionou. Você tem alguma solução para que funcione com páginas com extensão .php?

    Alex Araujo

    Comigo funcionou, porém com um pequeno problema na atualização, minhas páginas são todas em php. Coloque seu código completo por favor.

Alantiel otimo tutoraiLL, O meu problema é que não estou conseguindo recuperar os arquivos.js (jquery) dentro da div (Conteudo), buga tudo na hora q chama a pagina principal.php, você teria esta solução.
abx

ex:

function pageload(hash) {
if(hash) {
$("#Conteudo").load(hash);
} else {

$("#Conteudo").load("principal.php");
}
}

$(document).ready(
function()
{
// Historico de navegação
$.history.init(pageload);
$("a[@rel='pg']").click(function(){
var hash = this.href;
hash = hash.replace(/^.*#/, '');
$.historyLoad(hash);
return false;
});
}
);

Como eu faço pra funcionar jquery dentro da div Conteudo, alguem poderia me ajudar

Galera estou com um problema, nada com o plugin, se alguem poder me ajudar…

Seguinte meu menu é em flash, entao eu criei uma função para fazer os esquema do historico, o problema é que com flash, eu nao posso mudar a url e chamar uma função javascript ao mesmo tempo, não da pra usar mais de um getUrl, eu eu queria saber se tem como eu mudar a url do navegador via js.
Para ficar assim http://www.meusite.com.br/#algumacoisa.

ja tentei assim location.replace(url); e assim location.href = url;

No mozilla tudo otimo mas sabem como é o ie sempre tem algo para atrapalhar o cara…

Obrigado.

No aguardo.

Salve Salve gallera. sera que alguem poderia me ajudar!

página 1
página 2
página 3

como eu estou utilizando alguns plugins jquery (slideShow,galleryView)na pagina principal,
acontece o seguinte na hora q carrega a pagina 1 (principal). não funciona, não reconhece os scripts jquery, alguem sabeiria me dizer o porque

Mto obrigado.
Abx

    Diego, primeiramente verifique com o firebug na parte de rede o que esta sendo carregado dai assim você mais saber se a pagina esta carregando tudo, depois vale também usar o webdeveloper pra ver se nao esta dando tem um erro no java script, também tem que ver se os teus plugins são compativeis com a versão do jquery que tu esta utilizando, uma vez eu atualizei o jjquery mas não tinha pego a nova versao do blockUi dai ele nao funcionava também.

    E por ultimo, eu percei uma coisa com esse plugin history, que toda vez que muda url com o # mesmo que tu nao tenha indicado ela na function inicial ele mesmo assim tenta fazer o load, não tentei testar com outros plugins mas acho que nao deve funcionar com outros plugins que usa ancora.

    function pageload(hash) {
    //-> Aqui ele verifica se tem algum hash, se nao tiver nenum ele da um empty, ou seja ele limpa (deixa sem nada) dentro do teu elemento html, se tu tem algo dentro desse elemento coloca em um arquivo separado e no lugar de empty da um load nesse teu arquivo
    if(hash) {

    $("#load").load(hash + ".html");
    } else {
    $("#load").empty();
    }
    }

    $(document).ready(function(){
    //->Aqui tu inicia o plugin, aqui ele chama a função acima.
    $.historyInit(pageload);

    $("a[@rel=´imasters´]").click(function(){
    var hash = this.href;
    hash = hash.replace(/^.*#/, ´´);
    $.historyLoad(hash);
    return false;
    });
    });

    Bom espero ter ajudado, Posta ae depois pra saber se conseguiu.

Alex Araujo

Todos os scripts jquery devem ser chamados no index, se mesmo assim não funcionar vc deve usar o live() .

Pessoal alguem poderia me ajudar,
página 1
a unica diferenca ‘e que estou desenvolvendo os botoes em flash, alguem saberia me informa como ficaria!

on (press) {
getURL(‘#principal.php’);
}

Alguem consegui a solução em flash para menu em flash?
Estou com o mesmo problema que o Alex Araujo..

Galera estou com o mesmo problema alguem poderiiia nos ajudar? como ficaria passar o parametro da div no action do menu em flash.

Ola…
Como para usar onload para carregar assim carregar, por exemplo a home?

Mas como sempre o IEaca tem qeu estragar a festa, no IE não muda de pagina com a função para carregar

Alex Araujo

O problema para que usa menu em flash é capturar o evento click do flash para o histórico funcionar perfeitamente. Se alguém souber posta ai

Roberto brigadaum pela ajuuda mas msm assim naum consegui resolver o problema,
o problema esta nesta linha:
$(“a[@rel=´imasters´]“).click(function(){

o meu menu esta em flash ele esta assim:
on (press) {
getURL(‘#principal.php’);
}

eu ja tentei assim tbm mas nada
on (press) {
getURL(‘#principal.php’, ‘imasters’);
}

alguem sabe como recuperar o evento click?

    Eu estou rodando a depuracao do codigo no IE e aparece esse erro:
    LOG: [cycle] terminating; zero elements found by selector
    Exceção descartada e não detectada jquery-1.4.2.js

    alguem poderia me ajuudar com esse problema
    abx

    Alex Araujo

    O lance ta no javascript entender que o botão flash foi clicado, por isto que não esta funcionando corretamente. No código original pegamos o evento click do elemento “a” o lance é fazer o javascript pegar o evento click do elemento flash, não sei se isto é possível. Alguém poderia dar um help

    $(“?´”).click(function(){ Qual elemento que coloco onde esta a interrogação ?

pq os scripts jquery não funciona dentro da div carregada?

Este plugin parece nao estar funcionando com o jquery 1.4.2 – Peguei o exemplo e fiz um copy – paste mudando apenas a biblioteca para a versao que eu tenho (1.4.2) ele da erro logo de cara nao deixando iniciar ($.historyInit) .

Alguem ta com o mesmo problema?? No site oficial do Jquery (no forum) e informado que o plugim nao esta sendo mandido atualizado….

Pra mim também não ta funcionando na versão 1.4.2 se alguém conseguir resolver da um grito…..

    Paulo de Tarso Furtado Machado

    Pessoal, o erro que deve estar ocorrendo deve ser nesse trecho:

    $(“a[@rel=´imasters´]“)

    O que acontece é que o “@” não deve ser mais utilizado. Dessa forma, ficaria assim:

    $(“a[rel=´imasters´]“)

Parece que a função $.historyInit agora se chama $.history.init

Não tenho certeza, mas se tiverem com erro, dêem uma olhada aí

Como faço para o history funcionar em uma load de _POST?

onsubmit=”LoadForm(this, ‘centro’);return false;”

function LoadForm(_1,_2){var _3=new Object({“ajax”:true});var _4=_1.elements;for(var i=0;i=0){_3[_5.name]=_5.options[_5.selectedIndex].value;}break;case “select-multiple”:for(var j=0;j<_5.options.length;j++){if(_5.options[j].selected){_3[_5.name]=_5.options[j].value;}}break;}}}$.ajax({beforeSend:function(){document.getElementById(_2).innerHTML="Buscando…“;}});$(“#”+_2).load(_1.action,_3,function(){makeLinks();});};function Load(_7,_8){$.ajax({beforeSend:function(){document.getElementById(_8).innerHTML=” Carregando…“;}});$(“#”+_8).load(_7,{“ajax”:true},function(){makeLinks();});};

João Paulo Maida

Baixei o codigo do exemplo e funcionou direitinho mas o codigo postado aqui na pagina possui um erro na linha:

hash = hash.replace(/^.*#/, ´´);

o correto é

hash = hash.replace(/^.*#/, ”);

Espero ter ajudado

bruno

O problema aqui é quando eu acesso diretamente:
http://www.alantiel.com/~file/jqueryhistory/3

Ele exibe o conteúdo da página 3.html sem o container global.
Precisamos então identificar quando a url é acessada diretamente e direcionar para o container global interpretar com hash tag.

Resumo:

http://www.alantiel.com/~file/jqueryhistory/3
redireciona para
http://www.alantiel.com/~file/jqueryhistory/#3

Felipe Andres

Adorei esse plugin!

Só tenho uma duvida, me ajudem se souberem! eu tenho uma página com 4 divs para carregar conteudo dinâmico (um para banner, outro para side bar direita, terceiro para conteúdo central e o ultimo para side bar esquerda). Ez fiz isso porque muitas das páginas terão o mesmo side bar, mesmo banner.

Dependendo do link que eu clicar, vai carregar um conteudo diferente em cada div. Tem como fazer isso ou precisarei adaptar o sistema e usar um único div?

Gabriel

Eu estou usando $(“a.loader”).live(‘click’,… no lugar da function q executa o load, como funciona dessa maneira?

fabiophp@ymail.com

Interessante, mas será que alguém consegue explicar como isso http://denizardo12.wix.com/dze-serralheria-
pode ser feito.
Você podem ver que aparentemente o conteudo está sendo atualizado sem atualizar a pagina inteira, porém, além de atualizar a url, ao clicar no historico voltar e avançar a pagina muda conforme se estivesse sendo atualizado sem ajax.
Como pode isso ?

Diego Moraes

Alantiel, testei o seu código e funcionou perfeitamente. É fantástico. Estava procurando por essa solução desde 2009 e agora vc traz ela assim, pronta, funcionando. Uma beleza!.
Obrigado!

Qual a sua opinião?