Bem… Começarei os posts sobre AJAX com esse “esqueleto” de uma biblioteca, orientada a objeto, para aplicações em AJAX.
O código abaixo deve ser colocado em um arquivo “max_ajax.js” ou outro nome de sua escolha. Mas no final desse comentário eu anexei os 3 arquivos citados aqui neste post.
/**
* @author Fábio Miranda Costa - www.meiocodigo.com
* @version 0.26
* Pequena biblioteca para uso geral em Ajax.
* bugs conhecidos: Não conversa muito bem com tabelas.
* Testado com IE 6 e firefox 2.
* Qualquer dúvida mande e-mail para meiocodigo@gmail.com ou simplesmente comente.
*/
if(typeof window.max === "undefined") var max = new Object();
Esse inicio apenas verifica a existência do objeto max antes de criá-lo para ser possível acrescentar mais de uma das bibliotecas max.
Aos poucos eu irei postando outras bibliotecas que eu fiz para não ficar com muito conteúdo em um só post.
Métodos
Construtor
/**
* Construtor da classe max.Ajax
*
* @param {String} url - a url do arquivo que receberá a chamada ajax
* @param {Object} options - um objeto que conterá as possíveis opções, entre elas estão:
* update (opcional) - um id de um nó DOM que receberá a resposta do servidor.
* onComplete (opcional) - função que será executada logo após o servidor ter respondido ao pedido.
*
*/
max.Ajax = function(url,options){
Este é o método construtor da classe max.Ajax. Como ele podemos inicializar as variáveis usadas internamente em um objeto desta classe.
Se você quizer aprender alguma coisa sobre Javascript e orientação a objeto vá para o site www.w3schools.com que é um site excelente para iniciantes, aprendi muita coisa lá no inicio.
Bem voltando ao código inicialmente temos a declaração do construtor como sendo uma função que faz as seguintes coisas:
this.xmlHttp = this.createXMLHttp();//criação do objeto que tratará da nossa requisição ao servidor
Cria um XMLHttpObject para fazer as requisições assincronamente ao servidor.
this.url = url;
Inicializa a variável url pertencente a classe com o primeiro valor passado por parâmetro na inicialização do objeto. Este valor deve ser a url para o arquivo que deve ser enviada a requisição Ajax.
this.update = options.update || null;//se não for definida um id para fazer o update, this.update = null, caso contrário this.update = options.update
Inicializa a variável update pertencente a classe com o valor de options.update se esta for declarada ou inicializa ela com null se não tiver sido declarada. Este valor deve ser o id de algum nó DOM no seu HTML, este nó receberá o conteúdo que foi retornado pelo arquivo que recebeu a requisição Ajax. (complicado? :S)
this.onComplete = options.onComplete || function(){};//se tiver sido definida uma função para ser executado ao final da requisição então this.onComplete = options.onComplete senão this.onComplete = null;
};
Inicializa a variável onComplete pertencente a classe com o valor de option.onComplete, que deve ser sempre uma função. A função que for passada por parâmetro nesse caso será executada logo após a requisição Ajax ser finalizada.
Requisição Ajax por GET
max.Ajax.prototype = Object({
/**
* Método para enviar pedido get.
*/
get:
function(){
Este é o método de envio de uma requisição Ajax usando GET.
var thisObj = this;//fazendo referência a este objeto
Inicializamos a variável thisObj com o valor “this”.
Você deve estar pensando: “que babaca… pra que isso?”. Calma eu vou explicar depois por que inicializei essa variável dessa forma.
this.xmlHttp.onreadystatechange = function(){thisObj.updateFunc();};//esta linha define qual será a função que será executada quando nosso objeto xmlHttp tiver seu estado modificado, no caso updateFunc()
Aqui nós definimos um método ( “updateFunc()” ) que será executado toda vez que o estado do nosso XMLHttpObject mudar. Existem no máximo 5 possíveis valores para o estado, dependendo do browser.
- Estado 0 - A requisição assíncrona com o servidor não foi iniciada
- Estado 1 - A requisição foi inicializada
- Estado 2 - A requisição foi enviada
- Estado 3 - A requisição está sendo processsada
- Estado 4 - A requisição foi completada, com sucesso ou não.
Agora vem a explicação do por que inicializar a variável thisObj com “this”. Se eu tivesse feito essa mesma linha dessa forma:
this.xmlHttp.onreadystatechange = function(){this.updateFunc();};
vocês acham que funcionaria?
A resposta é não, por que o “this” neste caso está se referindo ao “this.xmlHttp” por estar dentro de seu escopo, por isso eu fiz uma atribuição ao max.Ajax (var thisObj = this;) e usei ele dentro do escopo do “this.xmlHttp”.
this.url += (this.url.indexOf("?") === -1)?"?":"&";
this.url += "ridwes="+Math.random();//adicionando uma variável randomica ao nosso get para que resolva um problema de cache que acredito que só aconteça no IE, chamei de ridwes por que acredito que ninguem teria uma variavel com esse nome, mas se for o caso...modifique hehe
Essas duas linhas acrescentam uma variável “ridwes” à nossa requisição. Esse nome eu escolhi arbitrariamente achando que ninguem escolheria tal nome para uma variável mas se você tiver escolhido então modifique o nome de sua variável ou modifique o código.
O objetivo de adicionar essa variável com valor randômico é de evitar problemas de cache que acontecem freqüentemente no IE.
this.xmlHttp.open("get",this.url,true);//define que o método usado para a nossa requisição será o 'get', a url do arquivo que receberá a requisição e o true indica que a chamada será assincrona.
Aqui temos, como o nome diz, a abertura de uma conexão com o servidor. O primeiro parâmetro da função open é o método utilizado para a comunicação (”get” ou “post”), o segundo é a url para o arquivo que receberá a chamada do browser, podem ser incluidas variáveis juntamente com ela, e o terceiro é um valor booleano que indica se a chamada será assíncrona (true) ou síncrona (false).
this.xmlHttp.send(null);//finalmente envia nosso pedido
},
E finalmente enviamos a chamada ao servidor, passando null como parametro. Veremos futuramente que se tivessemos usando o método “post” as variáveis seriam passadas por parâmetro ao invez do null.
Update nó DOM
/**
* Método executado toda vez que o xmlHttp mudar de estado.
*/
updateFunc:
function(){
Esta função, como já foi visto neste mesmo post, é executada no evento “readystatechange” do nosso objeto xmlHttp.
if (this.xmlHttp.readyState==4 || this.xmlHttp.readyState=="complete"){//verifica se o estado do xmlHttp é de completo, ou seja se a resposta do servidor já está "em mãos"
if (this.xmlHttp.status == 200){//verifica se o estatus do objeto é de sucesso, caso contrario o ideal seria mostrar um erro, mostrarei isso no futuro
if (this.update){
document.getElementById(this.update).innerHTML = this.xmlHttp.responseText;//joga o texto de resposta do servidor dentro do nó DOM especificado na opção update, se ela existir
}
this.onComplete(this.xmlHttp.responseText,this.xmlHttp.responseXML);//executa a função ao final da chamada ajax, também chamada de callback
}
}
},
Resolvi comentar todas essas linhas juntas porque são muitos “ifs”, um dentro do outro, pode acabar confundindo alguem.
A primeira linha é uma condição que verifica se a propriedade “readyState” do objeto xmlHttp está em seu estado final, ou seja, que a requisição ao servidor já retornou.
A segunda linha verifica se a propriedade estatus, do mesmo objeto xmlHttp, indica sucesso (o número 200 quer dizer que o servidor não retornou nenhuma mensagem de erro, no futuro veremos outros números e o que cada um deles representa).
A terceira linha verifica se foi passado por parâmetro algum id ao se criar um objeto max.Ajax, se tiver passado, na quarta linha o nó DOM com esse id receberá o responseText, ou seja, o texto de resposta do arquivo que chamamos em nossa requisição Ajax.
E finalmente na sexta linha temos a execução do método que foi passado por parâmetro no onComplete.
Se você não estiver entendendo muito bem veja o exemplo logo no final desse post que irá esclarecer melhor como essa biblioteca funciona.
Criação de objeto XMLHttp
/**
* Copiado na cara de pau, peguei de um artigo no Wrox.
* Método usado para a criação do objeto XMLHttp, peça chave para o ajax.
* Não explicarei em detalhes.
*/
createXMLHttp:
function(){
if(typeof XMLHttpRequest != "undefined")//entra em todos os navegadores menos o IE
return new XMLHttpRequest();
else if (window.ActiveXObject) {//no caso do IE
var aVersions = [ "MSXML2.XMLHttp.5.0","MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp","Microsoft.XMLHttp"];
//por cima, o que ela faz é verificar qual a versão mais recente do xmlHttp Object suportada pelo navegador e retorna o objeto
for (var i = 0; i < aVersions.length; i++) {
try{
var oXmlHttp = new ActiveXObject(aVersions[i]);
return oXmlHttp;
}catch (oError){}
}
}
throw new Error("Objeto XMLHttp não pode ser criado.");
}
});
Não falarei dessa função em detalhes, apenas coloquei alguns comentários aí no código. Mas basicamente essa função cria o objeto xmlHttp.
O código já está com comentários nas linhas mais importantes.
Criei um arquivo para testar a biblioteca com todas as opções possíveis.
Você pode copiar este texto em um arquivo HTML qualquer ou simplesmente baixar os arquivos anexados ao post.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="max_ajax_ref_blog.js" ></script>
<script type="text/javascript">
function testeAjax(thisObj){
var url = "teste.php";//criando uma string cujo valor corresponde à url do arquivo que receberá a requisição Ajax
url += "?valor_teste="+thisObj.innerHTML;//adicionando a variável "valor_teste" à url
var maxAjaxObj = new max.Ajax(url,{update:"teste",onComplete:
function(texto,xml){
alert("O innerHTML é:"+texto);
}
});//aqui estamos criando um objeto max.Ajax passando ao construtor como parâmetros uma url e um objeto com uma propriedade "update"
//cujo valor é o id "teste" indicando que o nó com id="teste" receberá o texto de resposta do servidor, depois temos o onComplete
//que é uma função e será executada logo após a resposta com sucesso do servidor
maxAjaxObj.get();//execução do método get para a nossa chamada Ajax.
}
window.onload = function(){//as função que estão dentro desse escopo só são executadas após todo o carregamento do site
document.getElementById("link_teste").onclick = function(){
testeAjax(this);
return false;
};//aqui nós estamos dizendo que o nó com id="link_teste" escutará esta função no evento "onclick"
}
</script>
</head>
<body>
<a id="link_teste" href="#">Texto para testar :D</a>
<div id="teste"></div>
</body>
</html>
O que esse código faz é enviar um pedido para o arquivo “teste.php” passando por get as variáveis ridwes com valor randomico (explicado no código) e a variável valor_teste que terá como valor a string “Texto para testar :D”.
meu arquivo teste.php ficou:
<?php
echo $_GET["valor_teste"];
?>
ou seja a resposta do servidor será exatamente o valor da variável “valor_teste” que é “Texto para testar :D”.
Traduzindo tudo, quando clicamos no link a requisição ao servidor é enviada quando o browser recebe a resposta da requisição um alerta é mostrado com o texto: “O innerHTML é: Texto para testar :D” e a div de id “teste” receberá também o mesmo texto de reposta do servidor (”Texto para testar :D”) por que eu coloquei como uma de minhas opções update:”teste”.
Espero ter sido claro =/
Qualquer dúvida comente por favor!!
Arquivos: