Criando layout tableless (div), com Ajax.

Enviar Post por Email Enviar Post por Email


Vamos fazer um site com Ajax, e para quem não souber o que é Ajax, vai um breve comentário.

Ajax significa Asynchronous Javascript And XML. Quer dizer que Ajax nada mais é do que uma capacidade (ferramenta, biblioteca), de fazer com que, em Javascript, eu possa fazer requisições HTTP (e, dependendo do navegador, posso fazer outros tipo de conexões). As requisições que o Ajax faz, podem ser síncronas ou assíncronas. Se for síncrona, o script ficará esperando o retorno da requisição para continuar a executar o seu código. Se for assíncrona, o script enviará a requisição e continuará a sua execução normalmente, e o retorno dessa requisição deverá ser tratado por uma outra função.

O XML nem sempre é usado para trafegar as informações em Ajax, mas como o nome já pegou, então ficou assim mesmo, mas podemos utilizar qualquer tipo de protocolo texto (como JSON), para trafegar as informações via Ajax.

O principal motivo para desenvolver uma página (web site) com Ajax, é faze-la ficar mais interativa com o usuário, mais dinâmica e criativa.

Para saber um pouco mais sobre Ajax, acesse AJAX (programação).

O Código HTML do Layout em Div

Vamos pegar o layout do post Definindo um Layout de Website sem Tabelas (Tableless), e retirar a parte mais a direita dele, para que a parte do meio do layout, contenha somente o menu e o miolo.

O código ficará como abaixo (arquivo index.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1" />
<title>Exemplo Estrutura de Site Tableless</title>

<link rel="stylesheet" type="text/css" href="estilo.css" />
<script language="javascript" src="script.js"></script>

</head>

<body>

<div id="todo">
	<div id="topo">
		<div id="logo">Logo</div>

		Aqui pode ser uma imagem de background e um texto.
	</div>

	<div id="meio">
		<div id="esquerda">
			<div id="menu">
				<div><a href="javascript: void(0);" onclick="ajaxHTMLmiolo('miolo', 'principal');">Principal</a></div>
				<div><a href="javascript: void(0);" onclick="ajaxHTMLmiolo('miolo', 'empresa');">Empresa</a></div>
				<div><a href="javascript: void(0);" onclick="ajaxHTMLmiolo('miolo', 'produtos');">Produtos</a></div>

				<div><a href="javascript: void(0);" onclick="ajaxHTMLmiolo('miolo', 'servicos');">Serviços</a></div>
				<div><a href="javascript: void(0);" onclick="ajaxHTMLmiolo('miolo', 'contato');">Contato</a></div>
			</div>
		</div>

		<div id="miolo">
			<div>Seção 1</div>
			<div>Seção 2</div>

			<div>Seção 3</div>
		</div>

		<div style="clear: both;"></div>
	</div>

	<div id="rodape">
		<div id="rodape_direita">
			Av. xxx yyy zzz, No 765<br/>
			Manaus - AM - CEP: 89000-000<br/>
			Email: <a href="mailto:seuemail@seudominio.com.br">seuemail@seudominio.com.br</a>

		</div>
	</div>
</div>

</body>
</html>

Maiores explicações sobre o layout, pode encontrar no link passado para o post.

As únicas mudanças foram a parte direita do layout que foi deletada, os menus agora são links (tag <a> com atributo onclick para chamada do Javascript), e foi inserida uma linha chamando o script script.js. Esse script contém a programação em Javascript para fazer a requisição em Ajax.

Uma outra mudança foi no arquivo de folhas de estilo estilo.css. Ele está sem os estilos da parte direita do layout e foi adicionado uma classe, para a frase que indica que o Ajax está carregando uma página, no nosso caso, a frase é simplesmente “Carregando…”, mas a classe está vazia, adicione os estilos que achar necessário.

O Código Javascript

O código Javascript precisa fazer tudo que o navegador faz automáticamente quando se coloca um link no web site: enviar a requisição, esperar pela resposta, pegar a resposta quando essa estiver pronta, tratar a resposta e exibir o que for necessário.

O código do arquivo script.js vai abaixo:

function getNewHttpRequest() {
	try {
		xmlhttp = new XMLHttpRequest();
	} catch(ee) {
		try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(E) {
				xmlhttp = false;
			}
		}
	}

	return(xmlhttp);
}

oAjax = getNewHttpRequest();

//Fila de conexões
fila = [];
ifila = 0;

// funcao para altear o conteudo do miolo
function ajaxHTMLmiolo(id, conteudo) {
	ajaxHTML(id, 'conteudo.php?conteudo='+conteudo);
}

//Executa a próxima conexão da fila
function ajaxRun() {
	//Abre a conexão
	oAjax.open("GET", fila[ifila][1], true);
	//Função para tratamento do retorno
	oAjax.onreadystatechange = function() {
		if (oAjax.readyState == 4) {
			//Mostra o HTML recebido
			retorno = unescape(oAjax.responseText.replace(/\+/g, " "));
			document.getElementById(fila[ifila][0]).innerHTML = retorno;
			//Roda o próximo
			ifila++;
			if(ifila < fila.length) setTimeout("ajaxRun()", 20);
		}
	};

	//Executa
	oAjax.send(null);
}

function ajaxHTML(id, url) {
	//Carregando...
	document.getElementById(id).innerHTML="<span class='carregando'>"+"Carregando...</span>";
	//Adiciona à fila
	fila[fila.length] = [id, url];
	//Se não há conexões pendentes, executa
	if((ifila+1) == fila.length) ajaxRun();
}

Agora vamos as explicações.

Começando pela função getNewHttpRequest, que não recebe parâmetro, e retorna um objeto XMLHTTP. Esse objeto é o responsável pelas requisições que iremos fazer. Os blocos try {…} catch() {…}, tentam pegar o objeto XMLHTTP de várias formas, por causa das várias formas de pegar esse objeto de navegadores diferentes. Se não conseguir nenhuma, retorna false.

Abaixo pego o objeto XMLHTTP e coloco na variável oAjax e logo abaixo defino as minhas variáveis da fila de requisições.

Por que uma fila de requisições?

Tenho uma fila de requisições para organizar as minhas requisições Ajax, pois sem ela, se o usuário clicar em vários links antes de esperar a resposta de uma requisição, ou eu tenho que instanciar vários objetos do Ajax (XMLHTML), ou vai dar um erro no script que executa a requisição, quando uma outra requisição é feita antes de esperar a primeira terminar. A fila resolve esse problema, pois somente uma requisição é feita por vez, e se houver outra requisição na fila, ela é chamada logo após a requisição atual terminar.

A função ajaxHTMLmiolo serve para fazer uma requisição em Ajax que pega o conteúdo do miolo da página, que é o conteúdo da tag div que tem o atributo id igual a miolo, nesse layout é onde o conteúdo do web site será exibido. Essa função recebe dois argumentos, o primeiro é o id do elemento que vai ser exibido o resultado da requisição, o segundo é uma string que é enviada para o servidor para saber qual conteúdo buscar para exibir. Ela chama a função genérica de requisição Ajax, a ajaxHTML, que recebe o id do elemento que vais ser alterado e a URL que vai ser requisitada.

A função ajaxHTML coloca uma requisição na fila de requisições e tenta fazer essa requisição, se a fila estiver vazia, chamando a função ajaxRun, se não estiver vazia, ela não faz nada, pois assim que for a vez da requisição colocada, ela será feita.

A função ajaxRun pega a requisição que está na vez, na fila de requisições, e a executa, pelo método GET. A linha

	oAjax.open("GET", fila[ifila][1], true);

diz que é para abrir a conexão com a URL que está na fila, pelo método GET. O último parâmetro quer dizer que essa requisição tem que ser feita pelo modo assíncrono. Se o último parâmetro for false, a requisição seria feita no modo síncrono.

Para saber mais sobre o método GET, acesse Como Funciona os Métodos GET e POST – Diferenças.

Na linha

	oAjax.onreadystatechange = function() {

estou informando ao objeto que a função seguinte é a função que eu quero que ele execute quando o estado da minha requisição mudar. Essa função normalmente é chamada de função de callback, ela fica esperando algum evento acontecer para executar, sem interromper a execução do código. Nesse caso, ela espera o evento de alteração de estado da requisição ocorrer para ser chamada, logo, ela provavelmente será chamada mais de uma vez, pois durante uma requisição o estado muda algumas vezes.

Essa função de callback vai testar se o estado atual da requisição é o estado que eu quero, com a linha:

		if (oAjax.readyState == 4) {

O estado do objeto Ajax que eu quero é igual a 4, que é o estado onde a resposta foi lida por completo. Para ver uma lista dos estados do objeto Ajax, acesse XMLHttpRequest.

Após a resposta estar pronta, eu a pego e coloco em uma variável, fazendo uma substituição de todos os sinais de “mais” (‘+’), por um espaço em branco. Se faz essa substituição, pois a resposta vem codificada como URL, e nessa codificação, os espaços são convertidos em sinais de “mais” (‘+’). A linha que faz isso é a linha abaixo:

		retorno = unescape(oAjax.responseText.replace(/\+/g, " "));
		document.getElementById(fila[ifila][0]).innerHTML = retorno;

A outra linha pega o elemento que tem o atributo id igual ao que foi passado para a requisição e coloca a resposta como conteúdo desse elemento, no caso do elemento em questão (div), faz o conteúdo ser exibido, mas pode ser feito para qualquer tipo de conteúdo, até um campo hidden (escondido) ou para preencher um selectbox.

		ifila++;
		if(ifila < fila.length) setTimeout("ajaxRun()", 20);

As linhas acima fazem o controle da fila, a primeira incrementa a posição da fila, fazendo a próxima requisição ser lida, se houver. A segunda linha verifica se o tamanho da fila é maior que a posição atual de leitura da fila, se for, é porque ainda existe requisição a ser feita, então ele programa um timer para em 20 milisegundos, para ser executada essa requisição.

Aqui termina a função de callback, ela será executada após o envio da requisição.

A última linha da função ajaxRun

	oAjax.send(null);

faz com que a requisição seja feita (enviada). O parâmetro dela, passado como null, indica que não estou enviando nada na requisição, porque já enviei o que eu queria pela URL passada.

O Código PHP

O código em PHP serve para fornecer o conteúdo requisitado pelo Ajax, perceba que a nossa URL da requisição Ajax tem como endereço o arquivo conteudo.php, lá na função ajaxHTMLmiolo, e o código desse arquivo (conteudo.php), vai abaixo:

<?php

$conteudo = $_GET["conteudo"];

if($conteudo == "principal") {
	$fileToRead = "conteudo/principal.html";
}
else if($conteudo == "empresa") {
	$fileToRead = "conteudo/empresa.html";
}
else if($conteudo == "produtos") {
	$fileToRead = "conteudo/produtos.html";
}
else if($conteudo == "servicos") {
	$fileToRead = "conteudo/servicos.html";
}
else if($conteudo == "contato") {
	$fileToRead = "conteudo/contato.html";
}

$conteudoArquivo = file_get_contents($fileToRead);

print(urlencode($conteudoArquivo));

?>

Ele simplesmente pega o valor do “conteudo”, que foi passado pelo método GET (olha novamente a URL passada na função ajaxHTMLmiolo), e compara com as strings acima. Cada if faz ele colocar na variável $fileToRead um caminho para um arquivo. Na penúltima linha ele joga todo o conteúdo do arquivo para a variável $conteudoArquivo, e na última linha ele codifica para URL e imprime na “tela” com a função print. A impressão na tela, é a resposta que o Ajax pega. QUALQUER coisa que você imprima na tela, vai ser o retorno da sua requisição Ajax, até mesmo se der um erro no script PHP, caso esteja configurado para exibir o erro na tela, o Ajax vai pegar como retorno.

Não vou colocar o conteúdo dos arquivos HTML de resposta, mas você pode ver o exemplo todo rodando em http://www.comocriarsites.com/exemplos/SiteTablelessAjax/. Lá você mesmo pode pegar os arquivos HTML.

Enviar Post por Email Enviar Post por Email

16 Responses to “Criando layout tableless (div), com Ajax.”

  1. 1
    Diogo Says:

    Com relação a esta parte do código em php:

    ———————————
    <?php

    $conteudo = $_GET["conteudo"];

    if($conteudo == "principal") {
    $fileToRead = "conteudo/principal.html";
    … etc

    ——————————–
    Só é possivével chamar um código em html (principal.html no caso mostrado acima)? Ou tem como eu chamar uma página php? Pois tentei e não sei se fiz algum erro.

    Até mais

  2. 2
    Raoni Novellino Says:

    Olá Diogo, nessa parte do código eu apenas estou dizendo que o conteúdo da variável $fileToRead vai ser a string “conteudo/principal.html”, pois lá embaixo do código eu faço:

    $conteudoArquivo = file_get_contents($fileToRead);

    Que irá adicionar todo o conteúdo do arquivo que estiver em $fileToRead a variável $conteudoArquivo, para eu poder imprimir esse conteúdo na tela, fazendo assim ser o retorno do Ajax.

    Se você quiser fazer um arquivo PHP incluir outro arquivo PHP, fazendo todas as funções e códigos serem executados, faça um include ou um require:

    include(“caminho/para/arquivo.php”);
    require(“caminho/para/arquivo.php”);

    Lembre-se que no arquivo que está sendo incluído, deverá conter as tag para ser reconhecido um arquivo php, se não ele irá processar o arquivo como HTML.

    Valeu.

  3. 3
    Diogo Says:

    Obrigado Raoni Novellino pela resposta, eu consegui fazer graças ao que me disse, obrigado! Qualquer coisa se precisar, estou a disposição. Até mais!

  4. 4
    Diogo Says:

    Vou fazer uma pergunta mais complicada, não sei se alguem vai conseguir me responder, mas não custa tentar. No caso, eu fiz o seguinte,

    Esse conteudo_mostra.php é o PHP que eu chamo na página do conteudo.php, igual está no tutorial.

    Se eu colocar um link desta forma no conteudo_mostra.php:

    Voltar para os dados pessoais

    ainda continuarei atualizando o ‘miolo’.

    Não sei se entenderam até ai, se tiverem dúvidas me avisem!

    O que eu não consigo de maneira nenhuma, é saber, se tem uma forma de enviar por post ou get (não sei), dados de um formulário que estejam nessas páginas que aparecem no ‘miolo’ sem que eu tenha de ir para outra página, ou seja, ao clicar em um botão, enviar por post tudo o que preciso e daí somente atualizar o miolo. Tentei de algumas formas, mas não obtive sucesso.

    Se alguém souber, pode me adicionar no msn para conversarmos (diogo_cost@hotmail.com)? Ou se puder explicar aqui mesmo, caso prefira, seria muito bem vindo comentários que venham a ajudar.

    Atenciosamente
    Diogo

  5. 5
    Diogo Says:

    saiu como um link ali em cima, desculpem

    O link acima era para mostrar o seguinte

    a href=”javascript: void(0);” onclick=”ajaxHTMLmiolo(‘miolo’, ‘dados_pessoais_alterar’);” Voltar para os dados pessoais /a

    tirei as barrinhas, pois sai como comando no site.

  6. 6
    » WENDELL VAZ « Says:

    Parabéns por este seu Post.. Procurava por algo assim há muito tempo…
    Bom.. Estou testando a montagem do meu Site usando a sua teoria..
    Até então está indo tudo bem..
    Pelo que notei, as páginas são chamadas pelo link interno da Página-Mãe.. O que eu queria saber é se há alguma maneira de eu chamar as “Páginas-Filhas” por um link DIRETO, mas que seja exibida a estrutura completa e não apenas o CONTEÚDO da página.
    Tentei fazer isso colocando a chamada no Link (ex: http://www.estacaoinfo.com/2010/STA/AjaxPageManager.php?Atalhos) mas não funcionou…

    Seria possível um auxílio??
    Muito Obrigado, desde já!!

    » WENDELL VAZ «

  7. 7
    Raoni Novellino Says:

    Ola Diogo, eu vou escrever um post sobre isso.
    Isso pode ser feito com Ajax, ou com o antigo método de frame, mas o Ajax é mais atual e mais elegante.
    Abraços.

  8. 8
    Rafael Says:

    Opa, estou utilizando seu código, porém, ele não mostra formulário, e nem o PHP funciona…

    Poderia me dizer oque eu faço para ele funcionar corretamente?

    Grato desde já(se puder me responder no meu email!)

  9. 9
    Raoni Novellino Says:

    Olá Rafael, no final do post tem um exemplo desses arquivos funcionando, verifique se o exemplo funciona no seu navegador, se não funcionar, pode ser alguma coisa desabilitada no seu navegador, tipo o Javascript. O link para o exemplo é http://www.comocriarsites.com/exemplos/SiteTablelessAjax/.
    Vendo o código fonte desse exemplo, você pode achar os arquivos HTML que ele pega para carregar as seções.
    O exemplo não tem formulário, ele usa o Ajax para carregar o conteúdo das páginas quando clicar em um item do menu.

    Obrigado por ler e qualquer dúvida e sugestão são bem vindos.

  10. 10
    Brayan Says:

    Raoni Novellino SHOW de bola cara :D ajudou muitoo mesmo, apanhei um poco até ler a pergunta do diogo aqui nos comentários. Agora vai resolver meu problema hehe. é que tenho a página de catalogo com os menus, (aqui usei seu tutorial com ajax) dae cada menu chama todos os produtos da categoria, só que cada produto tb manda por post um id para chamar outra pagina de detalhes :D

    Resumindo, usei o post e get com php para imagem e detalhes e utilizei o ajax para catalogo

    Parabéns pelo post, muito bom mesmo. Sucesso!

  11. 11
    Raoni Novellino Says:

    Valeu pelo comentário, sucesso na sua página também.
    Abraço.

  12. 12
    Raoni Novellino Says:

    Ola Wendell, para acessar por um link direto, eu faria dessa forma:
    - Colocaria para a página ser chamada por outro arquivo PHP, com uma variável passada por parâmetro GET (http://www.comocriarsites.com/index.php?miolo=produtos). Esse arquivo PHP seria bem parecido com o código do arquivo “conteudo.php”, só que ao invés de retornar somente o miolo, ele exibiria a página inteira, colocando o miolo como uma variável ou utilizando um template (como o Smarty Template).

  13. 13
    Brayan Says:

    :D
    Graças a essa ajuda com o javascript eu consegui fazer uma pagina de detalhes para meus produtos com get/post
    site que desenvolvi utilizando isso tudo:
    http://alturl.com/3xf8p

  14. 14
    Raoni Novellino Says:

    Olá Brayan, muito bom os efeitos do site.
    Valeu pela visita.
    Abraço.

  15. 15
    cleitor Says:

    bom dia amigos, sou iniciante em ajax e php,e gostaria se possivel me esclaressesem se e possivel manter a pagina requisitada com o layout que ela foi montada, pois quando ela abre no miolo ela perde a configuração… aluguma dica? desde ja agradeço!!!

  16. 16
    Raoni Novellino Says:

    Olá Cleitor, eu não entendi direito a sua dúvida, você poderia explicar melhor, ou mostrar um exemplo do que você está falando?
    A configuração que você está falando é o estilo css da página?
    Obrigado.

Leave a Reply