<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JulioGreff.net &#187; Ajax</title>
	<atom:link href="http://juliogreff.net/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://juliogreff.net</link>
	<description>A mesma web, um novo estilo de desenvolvimento</description>
	<lastBuildDate>Sat, 07 May 2011 17:07:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Hijax: Ajax Acessível</title>
		<link>http://juliogreff.net/hijax-ajax-acessivel/</link>
		<comments>http://juliogreff.net/hijax-ajax-acessivel/#comments</comments>
		<pubDate>Thu, 22 May 2008 20:08:11 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Usabilidade/Acessibilidade]]></category>
		<category><![CDATA[acessibilidade]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[hijax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[kiss]]></category>

		<guid isPermaLink="false">http://juliogreff.blog.br/?p=145</guid>
		<description><![CDATA[De longe, um dos maiores problemas no uso de Ajax é a acessibilidade. A facilidade em atualizar apenas uma parte da página tornou os desenvolvedores menos preocupados com a acessibilidade de seus projetos. Sem JavaScript, sites inteiros tornam-se completamente inacessíveis. Então, qual a solução para esse problema? Para evitar que o caos venha a este [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/ajax-vs-moda-vs-performance/' rel='bookmark' title='Permanent Link: Ajax vs. Moda vs. Performance'>Ajax vs. Moda vs. Performance</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>De longe, um dos maiores problemas no uso de Ajax é a acessibilidade. A facilidade em atualizar apenas uma parte da página tornou os desenvolvedores menos preocupados com a acessibilidade de seus projetos. Sem JavaScript, sites inteiros tornam-se <strong>completamente inacessíveis</strong>. Então, qual a solução para esse problema?</p>
<p>Para evitar que o caos venha a este mundo, surge outra palavrinha: <strong>Hijax</strong>. Mas primeiro vamos voltar a algumas premissas do desenvolvimento web: <strong>aprimoramento progressivo</strong> (<strong>progressive enhancement</strong>) e <strong>degradação elegante</strong> (<strong>graceful degradation</strong>), e me desculpem se errei a tradução dos termos&#8230;</p>
<h3>Aprimoramento Progressivo &#8211; Primeiro o Conteúdo</h3>
<p>Ninguém começa (ou pelo menos não deveria começar) a desenvolver uma aplicação primeiro pela camada de comportamento, isso vai completamente contra a filosofia de desenvolvimento em camadas (primeiro o conteúdo, depois a apresentação e, por último, o comportamento).</p>
<p>A idéia é começar o desenvolvimento de baixo. Em outras palavras, desenvolva da maneira antiga, usando links como sempre se usou desde que a Internet é Internet, devolvendo páginas inteiras como resposta. Depois, somente depois, comece a adicionar funcionalidades <strong>que melhorem a experiência do usuário</strong> (nada de frescuras que o usuário só vai achar bonito, <a href="http://juliogreff.net/ajax-vs-acessibilidade/" title="Ajax vs. Acessibilidade">pra que reinventar o link?</a>).</p>
<h3>Degradação Elegante &#8211; Útil sem perder a elegância</h3>
<p>&#8220;Degradação elegante&#8221; significa perder alguns recursos sem perder suas funcionalidades. Pode-se perder algumas animações e outros fru-frus, mas perder acesso ao conteúdo é inadmissível. CSS não é tão importante quanto as informações que queremos mostrar. Nunca ouviu a frase &#8220;mais ajuda quem não atrapalha&#8221;? A idéia é a mesma.</p>
<p>O desenvolvimento progressivo e em camadas é o caminho mais rápido para a degradação elegante. Mesmo utilizando Ajax, o conteúdo ainda deve continuar acessível através de um link comum. É aí onde <strong>Hijax</strong> entra.</p>
<h3>Hijax &#8211; Seqüestrando os Links</h3>
<p>O próprio termo explica bem o uso da técnica. <a href="http://domscripting.com/blog/display/41" title="Hijax - DOM Scripting" rel="external">Hijax</a>, do inglês hijack (&#8220;seqüestrar&#8221;), quer dizer <strong>seqüestrar</strong> os links comuns, e transformá-los em links Ajax. Simples assim.</p>
<p>&#8220;Simples assim&#8221;? Bem, nem tanto, eu confesso. Seus scripts server-side precisam estar preparados para decidir se enviam o &#8220;pacote completo&#8221; ou a &#8220;versão básica&#8221; da página, se for uma requisição normal ou uma requisição assíncrona, respectivamente. Uma breve dica: header <code>X-Requested-With</code>. Duas versões do site? Nunca mais, isso morreu junto com o Netscape, há muito tempo.</p>
<p>Vale lembrar que somente o uso de Hijax não faz uma aplicação completamente acessível, usável e rica. Há muito mais a se pensar. Já falei sobre <a href="http://juliogreff.net/a-aplicacao-ajax-perfeita/" title="A Aplicação Ajax Perfeita">alguns aspectos para uma boa aplicação Ajax</a>, mas tenho absoluta certeza que não passei nem perto de tudo que é necessário. Mas tudo isso já é uma boa base a ser levada em consideração, e com isso já é possível criar algo melhor que muita coisa que existe por aí, tenha certeza. E você, tem feito seu dever de casa e seguido princípios para tornar sua aplicação disponível a todos?</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/ajax-vs-moda-vs-performance/' rel='bookmark' title='Permanent Link: Ajax vs. Moda vs. Performance'>Ajax vs. Moda vs. Performance</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/hijax-ajax-acessivel/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Upload Assíncrono de Arquivos com Mootools</title>
		<link>http://juliogreff.net/upload-assincrono-de-arquivos-com-mootools/</link>
		<comments>http://juliogreff.net/upload-assincrono-de-arquivos-com-mootools/#comments</comments>
		<pubDate>Thu, 08 May 2008 15:21:47 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[bibliotecas]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://juliogreff.blog.br/?p=140</guid>
		<description><![CDATA[Como todos sabem, Upload com Ajax não é praticável em ambiente web. Existem várias restrições de segurança que impedem que o JavaScript acesse o sistema de arquivos do cliente e envie dados binários através de uma requisição XMLHttpRequest. No entanto, é possível (e sempre foi) fazer Upload Assíncrono de arquivos, utilizando uma técnica até antiga, [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/mootools-eventos/' rel='bookmark' title='Permanent Link: Mootools &#8211; Eventos'>Mootools &#8211; Eventos</a></li>
<li><a href='http://juliogreff.net/mootools-chain/' rel='bookmark' title='Permanent Link: Mootools &#8211; Chain'>Mootools &#8211; Chain</a></li>
<li><a href='http://juliogreff.net/mootools-classes/' rel='bookmark' title='Permanent Link: Mootools &#8211; Classes'>Mootools &#8211; Classes</a></li>
<li><a href='http://juliogreff.net/mootools-menu-sanfona/' rel='bookmark' title='Permanent Link: Mootools &#8211; Menu Sanfona'>Mootools &#8211; Menu Sanfona</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Como todos sabem, <strong>Upload com Ajax</strong> não é praticável em ambiente web. Existem várias restrições de segurança que impedem que o JavaScript acesse o sistema de arquivos do cliente e envie dados binários através de uma requisição XMLHttpRequest. No entanto, é possível (e sempre foi) fazer <strong>Upload Assíncrono</strong> de arquivos, utilizando uma técnica até antiga, muito bem explorada por <a href="http://www.elmicox.com/2007/upload-assincrono-iframe-como-ajax-1-funcao-simples/" title="Upload Assíncrono - El Micox" rel="external friend">muitos</a> por aí.</p>
<p>Já havia tempo que eu queria escrever esse script, mas a coragem faltava, até que ele me foi necessário. Como uso <a href="http://mootools.net" title="Mootools - Lightweight JavaScript Framework" rel="external">Mootools</a>, não faria sentido usar funções autônomas, desperdiçando código. Então tomei coragem e fiz. Pronto, nem doeu&#8230;</p>
<h3>O Código</h3>
<p>Meu objetivo, nesse post, não é explicar a <strong>lógica</strong> por trás do script (farei isso em breve), mas sim deixar o <strong>código pronto</strong>, e explicar seu uso.</p>
<p class="left"><a href="http://juliogreff.net/scripts/async-upload/asyncUpload.js" title="Async Upload - Upload Assíncrono de Arquivos"><img src="http://juliogreff.net/wp-uploads/download-script.png" title="Download Async Upload" alt="Download Async Upload" /></a></p>
<p>Antes de tudo, você precisará da <a href="http://mootools.net/download/" title="Mootools - Lightweight JavaScript Framework" rel="external">Mootools</a> com os módulos necessários, o que suponho que você já possua. Depois, faça o download do <a href="http://juliogreff.net/scripts/async-upload/asyncUpload.js" title="Async Upload - Upload Assíncrono de Arquivos">Async Upload</a>. Agora, basta incluir os dois scripts em sua página.</p>
<pre><code>&lt;script type="text/javascript" src="mootools.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="asyncUpload.js"&gt;&lt;/script&gt;</code></pre>
<h3>Utilização</h3>
<p>Como não podia deixar de ser, o script funciona na submissão de um formulário. Ele a intercepta e a envia para um iframe escondido. Pra que tudo isso funcione, temos que definir isso no <code>onSubmit</code> de nosso formulário:</p>
<pre><code>$(window).addEvent("load", function() { // quando terminar de carregar...
  $("seu-formulario").addEvent("submit", function() { // e o nosso formulário for enviado...
    this.upload() // fazemos nosso upload, parecido (mas não é) com Ajax
  })
}</code></pre>
<h3>E cadê a URL?</h3>
<p>Como a Mootools nos dá muitas opções para trabalhar com DOM, não precisamos definir a URL no script. Essa URL vai ser retirada do próprio formulário, no <code>action</code>:</p>
<pre><code>&lt;form action="http://sua-url-para-envio/upload.php" id="seu-formulario"&gt;
  &lt;input type="file" name="fileToUpload" id="fileToUpload" /&gt;
&lt;/form&gt;</code></pre>
<h3>Elemento de Retorno</h3>
<p>Muito melhor do que elementos de retorno, podemos definir uma <strong>função</strong> para tratar o retorno do upload. Para isso, passamos um parâmetro para a função:</p>
<pre><code>$(window).addEvent("load", function() {
  $("seu-formulario").addEvent("submit", function() {
    this.upload({
      "onComplete": function(response) {
        $("elemento_de_retorno").setHTML(response)
      }
    })
  })
}</code></pre>
<p>Com o código acima, o resultado da requisição iria para uma div (ou algum outro elemento) de id &#8220;elemento_de_retorno&#8221;. É claro, pode-se fazer muito mais, mas fica a seu cargo decidir&#8230;</p>
<h3>Recebendo o Arquivo</h3>
<p>Apesar de assíncrono (ou Ajax disfarçado), esse upload funciona como um upload comum. No PHP, por exemplo, podemos receber o arquivo assim:</p>
<pre><code>move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "nome_do_arquivo.txt");</code></pre>
<h3>Exemplo e Download</h3>
<p>Caso queira dar uma olhada, <a href="http://juliogreff.net/scripts/async-upload/" title="Async Upload - Upload Assíncrono de Arquivos">deixei um exemplo na página de downloads</a>. Faça upload de um arquivo qualquer e veja o funcionamento! Caso deseje saber a lógica por trás de tudo isso, aguarde os próximos posts. Até mais!</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/mootools-eventos/' rel='bookmark' title='Permanent Link: Mootools &#8211; Eventos'>Mootools &#8211; Eventos</a></li>
<li><a href='http://juliogreff.net/mootools-chain/' rel='bookmark' title='Permanent Link: Mootools &#8211; Chain'>Mootools &#8211; Chain</a></li>
<li><a href='http://juliogreff.net/mootools-classes/' rel='bookmark' title='Permanent Link: Mootools &#8211; Classes'>Mootools &#8211; Classes</a></li>
<li><a href='http://juliogreff.net/mootools-menu-sanfona/' rel='bookmark' title='Permanent Link: Mootools &#8211; Menu Sanfona'>Mootools &#8211; Menu Sanfona</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/upload-assincrono-de-arquivos-com-mootools/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>ClientSide: Mostre seu Código!</title>
		<link>http://juliogreff.net/clientside-mostre-seu-codigo/</link>
		<comments>http://juliogreff.net/clientside-mostre-seu-codigo/#comments</comments>
		<pubDate>Sun, 23 Dec 2007 16:19:25 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebStandards]]></category>
		<category><![CDATA[web standards]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/clientside-mostre-seu-codigo/</guid>
		<description><![CDATA[Agora os desenvolvedores client-side (JavaScript, XHTML, CSS, XML e derivados) contam com mais uma fonte de informação, o ClientSide, lançado pelo Élcio, do fechaTag há alguns dias atrás. O site é focado em &#8220;ler sobre código, ler código e colaborar&#8221;, segundo o próprio Élcio. Não há muitos posts até o momento, mas o que já [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/cliente-x-seu-ego/' rel='bookmark' title='Permanent Link: Cliente x Seu Ego'>Cliente x Seu Ego</a></li>
<li><a href='http://juliogreff.net/o-que-voce-faz-em-4kb/' rel='bookmark' title='Permanent Link: O que você faz em 4Kb?'>O que você faz em 4Kb?</a></li>
<li><a href='http://juliogreff.net/back-button-improved/' rel='bookmark' title='Permanent Link: Back Button Improved!'>Back Button Improved!</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/ativando-o-botao-voltar/' rel='bookmark' title='Permanent Link: Ativando o Botão Voltar'>Ativando o Botão Voltar</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Agora os desenvolvedores client-side (JavaScript, XHTML, CSS, XML e derivados) contam com mais uma fonte de informação, o <a href="http://clientside.com.br" rel="external" title="ClientSide">ClientSide</a>, lançado pelo <a href="http://blog.elcio.com.br/" rel="external" title="fechaTag - Élcio Ferreira">Élcio, do fechaTag</a> há alguns dias atrás.</p>
<p>O site é focado em &#8220;ler sobre código, ler código e colaborar&#8221;, segundo o próprio Élcio. Não há muitos posts até o momento, mas o que já foi postado, tanto pelo Élcio quanto por outros colaboradores, é um conteúdo selecionado, e de boa qualidade.</p>
<p>Gostei muito da <a href="http://clientside.com.br/politica/" rel="external" title="Política do ClientSide">política do site</a>, bastante rígida quanto à seleção de conteúdo. Teremos uma boa referência se ela for cumprida. O cadastro e postagem são abertos a qualquer um, basta enviar bom conteúdo.</p>
<p>Já assinei o feed e me inscrevi. Falta acertar todos os dados do cadastro, e logo estarei postando algum conteúdo, talvez até exclusivo (se me vier alguma idéia). Se quiser, também sinta-se livre para <a href="http://clientside.com.br/wp-login.php?action=register" rel="external" title="Cadastrar-se no ClientSide">cadastrar-se</a> e começar a postar.</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/cliente-x-seu-ego/' rel='bookmark' title='Permanent Link: Cliente x Seu Ego'>Cliente x Seu Ego</a></li>
<li><a href='http://juliogreff.net/o-que-voce-faz-em-4kb/' rel='bookmark' title='Permanent Link: O que você faz em 4Kb?'>O que você faz em 4Kb?</a></li>
<li><a href='http://juliogreff.net/back-button-improved/' rel='bookmark' title='Permanent Link: Back Button Improved!'>Back Button Improved!</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/ativando-o-botao-voltar/' rel='bookmark' title='Permanent Link: Ativando o Botão Voltar'>Ativando o Botão Voltar</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/clientside-mostre-seu-codigo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ajax com a Mootools</title>
		<link>http://juliogreff.net/ajax-com-a-mootools/</link>
		<comments>http://juliogreff.net/ajax-com-a-mootools/#comments</comments>
		<pubDate>Sun, 24 Jun 2007 20:28:00 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[bibliotecas]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/ajax-com-a-mootools/</guid>
		<description><![CDATA[Sempre gostei de escrever minhas próprias funções para meus scripts, e nunca havia usado uma biblioteca JavaScript (não que eu não tenha tentado). Elas nunca se adaptavam ao que eu queria. Até o lançamento da Mootools 1.11, o qual ouvi falarem muito bem. Resolvi testar. Já temos a versão 1.2, então hora de atualizar! Motools [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/mootools-options/' rel='bookmark' title='Permanent Link: Mootools &#8211; Options'>Mootools &#8211; Options</a></li>
<li><a href='http://juliogreff.net/ajax-sem-o-x/' rel='bookmark' title='Permanent Link: Ajax sem o X'>Ajax sem o X</a></li>
<li><a href='http://juliogreff.net/mootools-eventos/' rel='bookmark' title='Permanent Link: Mootools &#8211; Eventos'>Mootools &#8211; Eventos</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Sempre gostei de escrever minhas próprias funções para meus scripts, e nunca havia usado uma biblioteca JavaScript (não que eu não tenha tentado). Elas nunca se adaptavam ao que eu queria. Até o lançamento da <a href="http://www.mootools.net" title="Mootools 1.11" rel="external">Mootools 1.11</a>, o qual ouvi falarem muito bem. Resolvi testar.</p>
<p class="post-update">Já temos a versão 1.2, então <a href="http://juliogreff.net/lancada-a-mootools-12/" title="Lançada a Mootools 1.2">hora de atualizar</a>!</p>
<p>Motools é uma biblioteca JavaScript orientada a objetos, muito modular, compacta e, na minha opinião, muito simples de usar (não tanto quanto a jQuery, foi por isso que gostei). Nesse post vou explicar como fazer as requisições assíncronas, vulgo Ajax.</p>
<h3>Fazendo o Download</h3>
<p>Vá em <a href="http://mootools.net" rel="external" title="Site da Mootools">http://mootools.net</a>, e faça o download da biblioteca. Escolha os módulos que achar necessário para usos futuros, mas inclua os seguintes: Core, Function, Array, String, Element e Ajax (sério?). Também escolha a compressão que quiser.</p>
<p>Feito isso, crie uma nova página, e inclua o script.</p>
<h3>Uma Requisição Simples</h3>
<p>Vamos fazer uma simples requisição, sem retorno algum, bastando informar ao servidor que alguma coisa aconteceu. A base para o uso de Ajax é a classe <code>Ajax</code> (isso mesmo, é assim que os construtores são chamados aqui, por serem baseados em um construtor <code>Class</code>, da própria biblioteca). Ela cria a requisição, mas não a executa. Essa parte fica a cargo do método <code>request</code>. Vamos ao código:</p>
<pre><code>var options = { "method": "get" };
var ajaxReq = new Ajax("http://localhost/informa_servidor", options).request();</code></pre>
<p>A classe possui apenas dois parâmetros que podem ser passados: <code>url</code> (String) e <code>options</code> (Object). Vamos ver todas mais adiante. Setei apenas <code>"method"</code>, pois o método padrão na biblioteca é POST. Um bug que encontrei: se você definer o método como &#8220;GET&#8221; em vez de &#8220;get&#8221;, a biblioteca tratará como sendo POST. Ou seja, use sempre letras minúsculas.</p>
<h3>Atualizando um Objeto</h3>
<p>Mais uma grande facilidade da Mootools (não que as outras também não tenham): não precisamos, necessariamente, criar uma função para ser executada quando a requisição for completada, podemos apenas definir um objeto a ser atualizado. Isso pode ser feito através da opção <code>update</code> (String ou Object). Mais um código:</p>
<pre><code>var options = { "method": "get", "update": "elementoPraAtualizar" };
var ajaxReq = new Ajax("http://localhost/retorna_resposta", options);
</code></pre>
<p>Essa seria uma maneira de retornar uma resposta &#8220;estática&#8221; do servidor, já que não enviamos nenhum dado junto com a requisição. Aí entra a opção <code>data</code> (String, nesse caso), que levará a query string juntamente com a requisição, assim: &#8220;parametro=valor&amp;outro=valor&#8221;.</p>
<p>A opção <code>data</code>, além de uma query string, pode ser um objeto ou um elemento <code>&lt;form&gt;</code>. A biblioteca se encarrega de transforma-los em query string, seja para envio pelo método GET ou POST. Legal, né? Outro exemplo:</p>
<pre><code>var queryString = { "id": userId, "action": "getName" };
var options = { "method": "get", "update": "algumElemento", "data": queryString };
var ajaxReq = new Ajax("http://localhost/envia_query_string", options);
</code></pre>
<h3>Função onComplete</h3>
<p>Muitas vezes não se torna necessário tratar a resposta da requisição, bastando passa-la diretamente para um elemento. A diferença é quando os dados devem ser analisados, testados, interpretados ou qualquer coisa do gênero, ou seja, precisamos de uma função pra ser executada no final da requisição. A Mootools também permite isso através da opção <code>onComplete</code>. Aí fica a nosso cargo implementar toda a complexidade necessária na função. Código de novo:</p>
<pre><code>var options = { "method": "get", "onComplete": onComplete };
var ajaxReq = new Ajax("http://localhost/requer_tratamento", options);
var onComplete = function(text) {
  var returnText = text.treatRequest();
  $("placeholder").empty().setHTML(returnText);
  applicationStatus = 0;
}</code></pre>
<p>Como podemos ver, temos todo o controle de volta quando precisamos. Seria melhor ainda se pudéssemos ter controle sobre o XML que é enviado&#8230; Que bom, pois podemos ter controle sobre ele. Para a função do <code>onComplete</code>, são passados dois parâmetros: o texto e o XML. Muito bom, não?</p>
<h3>Enviando um Formulário</h3>
<p>Essa também é ótima. Podemos enviar um formulário inteiro com apenas um comando, que é uma extensão da classe <code>Element</code> disponibilizada pelo módulo Ajax. Através da função <code>$</code>, obtemos o formulário, e pelo método <code>send</code> enviamos a requisição via POST.</p>
<pre><code>var formReq = $("meuForm").send();</code></pre>
<p>O método <code>send</code> possui apenas o parâmetro <code>options</code>, sem URL (ela é retirada do action do formulário). As opções podem ser as mesmas de <code>Ajax.request</code>.</p>
<h3>Interpretando Scripts</h3>
<p>Todo mundo sabe que às vezes é necessário interpretar toda ou uma parte da requisição, enviada como JavaScript. A Mootools disponibiliza mais duas opções para esses casos: <code>evalScripts</code> e <code>evalResponse</code> (ambos Boolean).</p>
<p>Através de <code>evalScripts</code>, a biblioteca interpreta todos os scripts da requisição que estiverem entre as tags <code>&lt;script&gt;</code>. Caso o header recebido seja &#8220;text/javascript&#8221; ou &#8220;text/ecmascript&#8221;, toda a requisição é interpretada.</p>
<p>Já a opção <code>evalResponse</code> é mais generalista. Mesmo que seu header seja &#8220;text/html&#8221;, &#8220;text/xml&#8221; ou qualquer outra coisa, toda a requisição será interpretada. Não interessa o tipo de conteúdo. Parece ambíguo, mas as duas opções têm seu uso real.</p>
<p>Lembrando: as duas opções interpretam os scripts no escopo global.</p>
<h3>Recebendo os Dados</h3>
<p>Como sei que muita gente tem problemas na hora de receber os dados no lado do servidor, no caso do método POST, veja como <a href="http://juliogreff.net/utilizando-o-metodo-post/#recebendo-os-dados" title="Utilizando o Método POST - Recebendo os Dados">receber os dados</a> pelo PHP, de maneira simples e rápida.</p>
<p>Quanto à biblioteca, tem alguns pequenos defeitos. Aquele bug do &#8220;GET&#8221; que eu falei acima, a falta de um controle sobre os stateChanges, que foi retirado nessa versão, enfim. Mas isso não torna a biblioteca menos útil.</p>
<p>E vou ficando por aqui. Até!</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/mootools-options/' rel='bookmark' title='Permanent Link: Mootools &#8211; Options'>Mootools &#8211; Options</a></li>
<li><a href='http://juliogreff.net/ajax-sem-o-x/' rel='bookmark' title='Permanent Link: Ajax sem o X'>Ajax sem o X</a></li>
<li><a href='http://juliogreff.net/mootools-eventos/' rel='bookmark' title='Permanent Link: Mootools &#8211; Eventos'>Mootools &#8211; Eventos</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/ajax-com-a-mootools/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Estatísticas para Navegação via JavaScript</title>
		<link>http://juliogreff.net/estatisticas-para-navegacao-via-javascript/</link>
		<comments>http://juliogreff.net/estatisticas-para-navegacao-via-javascript/#comments</comments>
		<pubDate>Fri, 22 Jun 2007 22:18:38 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Destaques]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[estatísticas]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/estatisticas-para-navegacao-via-javascript/</guid>
		<description><![CDATA[Pode até parecer, mas essa não é uma série &#8220;Utilidades para Navegação via JavaScript&#8221; (eu já havia escrito &#8220;Histórico para Navegação via JavaScript&#8221;, a quem interessar possa). É apenas coincidência&#8230; Quando fazemos a navegação via JavaScript (leia-se também Ajax), geralmente não temos controle sobre quem navega em nossa página. Tudo que temos é o log [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/historico-para-navegacao-via-javascript/' rel='bookmark' title='Permanent Link: Histórico para Navegação via JavaScript'>Histórico para Navegação via JavaScript</a></li>
<li><a href='http://juliogreff.net/botao-voltar-para-ie/' rel='bookmark' title='Permanent Link: Botão Voltar para IE'>Botão Voltar para IE</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/javascript-object-notation/' rel='bookmark' title='Permanent Link: JavaScript Object Notation'>JavaScript Object Notation</a></li>
<li><a href='http://juliogreff.net/responsexml/' rel='bookmark' title='Permanent Link: ResponseXML'>ResponseXML</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Pode até parecer, mas essa não é uma série &#8220;Utilidades para Navegação via JavaScript&#8221; (eu já havia escrito <a href="http://juliogreff.net/historico-para-navegacao-via-javascript" title="Histórico para Navegação via JavaScript">&#8220;Histórico para Navegação via JavaScript&#8221;</a>, a quem interessar possa). É apenas coincidência&#8230;</p>
<p>Quando fazemos a navegação via JavaScript (leia-se também Ajax), geralmente não temos controle sobre quem navega em nossa página. Tudo que temos é o log do servidor. Isso nem chega perto das ferramentas de estatísca que temos por aí, e muitas são de graça. Tudo acontece porque essas ferramentas funcionam, geralmente, através de JavaScript, que envia os dados para processamento e armazenamento. Como a navegação via JavaScript não nos dá o luxo de um reload, esse código não é executado, fazendo com que somente as visitas à pagina raiz sejam contadas.</p>
<p>Uma das ferramentas que permite a análise das estatísticas para navegação via JavaScript é o <a href="http://analytics.google.com" title="Google Analytics" rel="external">Google Analytics</a>. Poderíamos utilizar o <strong>Site Overlay</strong>, que mostra as estatísticas de clique em determinadas áreas do site, mas ele não permite que cruzemos as informações. A idéia então é passar as informações para o <strong>Top Content</strong>, através da função <code>urchinTracker</code>, com um truque simples. Observe o código abaixo:</p>
<pre><code>&lt;a href="http://juliogreff.net/" onclick="urchinTracker('track/home')"&gt;JulioGreff&lt;/a&gt;</code></pre>
<p>O evento onclick do link acima dispara a função <code>urchinTracker</code>, que irá interpretar o parâmetro passado como um pageview. Aquele parâmetro será equivalente a uma URL, e você poderá filtrar os dados e cruza-los no Analytics.</p>
<p>O esquema é basicamente esse. Podemos adicionar a função <code>urchinTracker</code> não somente em links, e não somente em onclicks, mas em qualquer coisa relevante você queira monitorar e analisar mais tarde. Até aqui não há nada que quem leu documentação do Analytics não saiba. A parte legal começa agora.</p>
<p>Primeiramente, não devemos misturar marcação com script, conteúdo com comportamento. Ou seja, sem onclicks. Isso só nos deixa uma opção: a função mágica, <code>addEvent</code>:</p>
<pre><code>var addEvent = function(obj, evType, fn, arg){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, true)}
  if (obj.attachEvent){
    obj.attachEvent("on"+evType, fn)}
}</code></pre>
<p>Essa é a &#8220;versão básica&#8221;. Se você tem algo mais completo, melhor. Ela não é o foco do post. Para não ter que escrever muito código, eu optei pela seguinte técnica: adicionar o tracker para todos os elementos que tiverem uma determinada classe CSS, e ela seria usada como label também. Novamente, mais uma função utilitária:</p>
<pre><code>var getElementsByClassName = function(className) {
  var elements = document.getElementsByTagName("*"), array = [];
  for(var i = 0; i &lt; elements.length; i++) {
    if(elements[i].className.search(className) &gt; -1) array.push(elements[i]);
  }
  return array;
}</code></pre>
<p>Essa é a &#8220;versão pré-básica alfa&#8221;. É altamente recomendável que você use uma função decente em um ambiente real, já que <code>getElementsByClassName("track")</code> retornaria tanto a classe &#8220;track&#8221; quanto &#8220;tracker&#8221;, quanto &#8220;&#8212;track&#8212;&#8221;, enfim.</p>
<p>A função que fará o serviço sujo é <code>Track</code>, em versão de testes, embora utilizável. Ela pega todos os elementos com a classe &#8220;track&#8221;, e passa as próximas classes como parâmetro para o Analytics, no evento onclick. A função é a seguinte:</p>
<pre><code>var Track = function() {
  // Pega todos elementos com classe "track"
  var elements = getElementsByClassName("track");
  for(var i = 0; i &lt; elements.length; i++) {
    // Pra cada um deles adiciona o "onclick"
    addEvent(elements[i], "click", function() {
	  // Aqui uso o nome da classe como label pro Analytics
	  urchinTracker(elements[i].className.split(" ")[1].replace(/-/g, "/");
	});
  }
}
// Quando a janela carregar, "trackeio" os elementos
addEvent(window, "load", Track);
</code></pre>
<p>A menos que você queira algo mais específico, não é necessário modificar o código. Você só terá que modificar os elementos que você deseja monitorar, adicionando a classe &#8220;track $&#8221;, onde $ é o label que você deseja que o elemento tenha. Os traços &#8220;-&#8221; serão convertidos para barras.</p>
<p>Veja um exemplo, retirado do novo tema do blog, no formulário de busca:</p>
<pre><code>&lt;input type="submit" class="track geral-busca" value="Buscar" /&gt;</code></pre>
<p>Você pode me perguntar: &#8220;E minhas classes declaradas no CSS?&#8221;. No meu CSS, apenas adicionei uma regra para &#8220;geral-busca&#8221;, como se fosse um ID, mas modifiquei o código para enviar ao Analytics apenas a segunda classe (&#8220;geral-busca&#8221;, no meu caso), sendo que as seguintes são completamente ignoradas, e a primeira serve apenas para &#8220;seleção&#8221; pelo script.</p>
<p>Agora vá para o Analytics. No seu Dashboard, clique em <strong>Content &gt; Top Content</strong>. Ali você terá todas as URLs de seu site monitoradas pelo Analytics (as que tiveram visitas).</p>
<p class="center"><img src="http://juliogreff.net/wp-uploads/top-content.png" title="Top Content do Google Analytics" alt="Top Content do Google Analytics" /></p>
<p>Assim como &#8220;/url/qualquer&#8221;, seus labels &#8220;artificiais&#8221; também estarão ali (dentro de 48 horas, às vezes menos). Nessa tela, você pode adicionar um filtro para mostrar apenas os labels que você criou, e então analisar os dados. Para isso, use o campo &#8220;Find URL&#8221;.</p>
<p class="center"><img src="http://juliogreff.net/wp-uploads/filtrando-labels.png" title="Filtrando Labels no Google Analytics" alt="Filtrando Labels no Google Analytics" /></p>
<p>Agora só temos que cruzar os dados. Para isso, apenas clique no label, e na página que abrirá, escolha os dados que você deseja cruzar no campo &#8220;Segment&#8221;.</p>
<p class="center"><img src="http://juliogreff.net/wp-uploads/cruzando-dados.png" title="Cruzando Dados no Google Analytics" alt="Cruzando Dados no Google Analytics" /></p>
<p>Como não sou nenhum mestre do marketing, essa parte ficará com você. Pra complementar o texto, eu recomendo que você leia os seguintes textos, <a href="http://www.revolucao.etc.br" rel="external" title="Revolução Etc">escritos pelo Henrique, do Revolução Etc</a>:</p>
<ul>
<li><a href="http://www.revolucao.etc.br/archives/estrategia-de-metricas-parte-1-metricas-para-probloggers/" rel="external" title="Estratégia de métricas parte 1: Métricas para ProBloggers">Estratégia de métricas parte 1: Métricas para ProBloggers</a></li>
<li><a href="http://www.revolucao.etc.br/archives/estrategia-de-metricas-parte-2-google-analytics-e-a-funcao-urchintracker/" rel="external" title="Estratégia de métricas parte 2: Google Analytics e a Função urchinTracker">Estratégia de métricas parte 2: Google Analytics e a Função urchinTracker</a></li>
</ul>
<p>Escrevi esse post me baseando na parte 2, atualizando para a nova interface do Analytics, e adicionando o script. Considero um erro encher o site de onclicks, principalmente vindo do Henrique, que preza tanto pela separação Conteúdo-Estilo-Comportamento. Fui!</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/historico-para-navegacao-via-javascript/' rel='bookmark' title='Permanent Link: Histórico para Navegação via JavaScript'>Histórico para Navegação via JavaScript</a></li>
<li><a href='http://juliogreff.net/botao-voltar-para-ie/' rel='bookmark' title='Permanent Link: Botão Voltar para IE'>Botão Voltar para IE</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/javascript-object-notation/' rel='bookmark' title='Permanent Link: JavaScript Object Notation'>JavaScript Object Notation</a></li>
<li><a href='http://juliogreff.net/responsexml/' rel='bookmark' title='Permanent Link: ResponseXML'>ResponseXML</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/estatisticas-para-navegacao-via-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Aplicação Ajax Perfeita</title>
		<link>http://juliogreff.net/a-aplicacao-ajax-perfeita/</link>
		<comments>http://juliogreff.net/a-aplicacao-ajax-perfeita/#comments</comments>
		<pubDate>Thu, 07 Jun 2007 16:39:00 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[acessibilidade]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[cross browser]]></category>
		<category><![CDATA[filosofia]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[usabilidade]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/a-aplicacao-ajax-perfeita/</guid>
		<description><![CDATA[Tempos atrás andei pensando sobre uma aplicação Ajax. O que ela deveria ser, como deveria funcionar, tudo o que precisaria ter. Incrementei a idéia, pensando na acessibilidade, usabilidade, unobstrusividade, essas coisas. Cheguei a conclusão que não existem muitas dessas por aí. Não que essa idéia fosse &#8220;a aplicação ajax perfeita&#8221;, mas sim a ideal. Demoraria [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/hijax-ajax-acessivel/' rel='bookmark' title='Permanent Link: Hijax: Ajax Acessível'>Hijax: Ajax Acessível</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-vs-moda-vs-performance/' rel='bookmark' title='Permanent Link: Ajax vs. Moda vs. Performance'>Ajax vs. Moda vs. Performance</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Tempos atrás andei pensando sobre uma aplicação Ajax. O que ela deveria ser, como deveria funcionar, tudo o que precisaria ter. Incrementei a idéia, pensando na <a href="http://juliogreff.net/ajax-vs-acessibilidade/">acessibilidade</a>, usabilidade, unobstrusividade, essas coisas. Cheguei a conclusão que não existem muitas dessas por aí.</p>
<p>Não que essa idéia fosse &#8220;a aplicação ajax perfeita&#8221;, mas sim a ideal. Demoraria muito a ser feita, mas eu consideraria uma obra de arte.</p>
<h3>Padronização</h3>
<p>Essa parte é a parte fácil, que todo mundo <strong>sempre</strong> deveria se dar ao trabalho de fazer: manter seu trabalho dentro dos web standards.</p>
<p>Validar sua marcação, seus CSSs, isso todo mundo faz (ou deveria). Mas às vezes um certo item é deixado de lado: seus XMLs, que não causariam muito problema, a não ser um XML em especial: os feeds. Ou seja, valide tudo que possa ser validado.</p>
<h3>Manutenção</h3>
<p>Código bom é código comentado. Disso ninguém discorda. Sempre comente seus códigos, tanto para seu uso em futuras manutenções e atualizaçãoes, quanto para seus visitantes que querem descobrir o segredo daquela técnica inovadora que você implementou. JavaScript ninguém esconde, e uma técnica nova deveria poder chegar a todos que quisessem, mesmo que seja investigando seu código. Melhor ainda se ele estiver comentado, mesmo que seja somente em partes mais obscuras.</p>
<p>E o tamanho do código não aumentaria? Sim, mas você só precisará comentar partes essenciais, aquelas mais complicadas que você sabe que irá esquecer com o tempo. Além do mais, se você esquecer de seu código, perderá muito tempo até lembrar o que cada parte faz.</p>
<h3>Compatibilidade</h3>
<p>Outra parte facílima, mas indispensável. Se tudo for seguido, nem tanto, mas ainda assim se torna muito mais agradável usar uma aplicação que funcione como deveria funcionar.</p>
<p>Com todas as opções de browsers existentes hoje, sempre haverá aquele que terá problemas (geralmente o azulzinho que todo mundo já conhece). Mas existem maneiras de amenizar o problema. Isso não só com Ajax, mas qualquer &#8220;defeito&#8221; de JavaScript e CSS que possa atrapalhar a experiência do usuário.</p>
<p>Essa parte pode, sem problemas, ser deixada para os frameworks já existentes, que fazem seu trabalho muito bem. A compatibilidade vem sendo muito focada por essas bibliotecas, facilitando, e muito, seu trabalho.</p>
<h3>Controle de readyStates</h3>
<p>Agora começa a parte divertida. Tudo que está logo acima qualquer um faz. Vamos começar adicionando nossos diferenciais.</p>
<p>Geralmente, costuma-se cuidar de apenas dois readyStates: 1 e 4 (aberto e carregado), que resultam no clássico &#8220;Carregando&#8230;&#8221; e a requisição completa. Não que seja necessário, mas um controle completo de estados poderia ser bom.</p>
<p>O usuário saber que sua requisição está sendo processada ajuda, já que não pensaria que a requisição travou (isso acontece bastante quando a requisição demora demais).</p>
<p>Coloquei os readyStates, o que significam e uma sugestão para o texto de carregamento. Os readyStates 0 e 4 não precisam disso, já que 0 não tem muito uso, e 4 terá sua própria função.</p>
<ul>
<li><strong>Não Inicializado (0)</strong></li>
<li><strong>Aberto (1)</strong>: &#8220;Abrindo Requisição&#8221; ou &#8220;Iniciando Requisição&#8221;</li>
<li><strong>Enviado (2)</strong>: &#8220;Enviando Dados&#8221;</li>
<li><strong>Recebendo (3)</strong>: &#8220;Carregando&#8221; ou &#8220;Recebendo Dados&#8221;</li>
<li><strong>Completo (4)</strong></li>
</ul>
<p>Não que seja necessário, mas também seria válido cuidar dos status da requisição também, pelo menos 200 (OK), 404, 500, e os outros erros mais comuns.</p>
<h3>Histórico</h3>
<p>Esse é o maior problema das aplicações Ajax. Já faz tempo que <a title="Ativando o Botão Voltar" href="http://juliogreff.net/ativando-o-botao-voltar/">as primeiras soluções para histórico apareceram</a>, e <a title="Histórico para Navegação via JavaScript" href="http://juliogreff.net/historico-para-navegacao-via-javascript/">outras melhoradas</a>, e ainda há centenas de aplicações que não se dão ao trabalho de implementar qualquer das soluções.</p>
<p>O histórico <strong>sempre</strong> deve ser implementado, mesmo que sua aplicação não queira dominar o mundo.</p>
<h3>Cache</h3>
<p>O cache, considerado uma praga por muitos, pode ser de uma grande ajuda para sua aplicação. Sempre que se faz uma requisição estática (que não muda em pouco tempo), deve-se usar o cache, pois quando refizermos essa requisição, ela terminará mais rápido.</p>
<p>Além do mais, usando o histórico, podemos guardar requisições &#8220;cacheadas&#8221; no próprio JavaScript. Assim, mais rápido ainda.</p>
<p>É claro que, em requisições dinâmicas, não devemos usar essa técnica. Ela pode prejudicar o usuário, pois não há maneira de atualizar a página através do F5.</p>
<h3>Filas de Requisição</h3>
<p>Todos sabem que se quando uma requisição estiver em andamento, e outra for iniciada, a primeira será cancelada.</p>
<p>Assim como o histórico, já existem milhares de soluções diferentes para <a title="Fila de Requisições em Ajax" href="http://juliogreff.net/fila-de-requisicoes-em-ajax/">fila de requisições</a>. Esse recurso deve também ser usado sempre que possível (ou seja, sempre). Isso pode evitar aborrecimentos ao usuário.</p>
<h3>Inobstrusividade</h3>
<p>Essa é a questão mais polêmica. Sua aplicação não deve usar JavaScript obstrusivo (ou usar o menos possível), fazendo-a de maneira que funcione corretamente em qualquer browser.</p>
<p>E o Ajax sem JavaScript, como fica? Também tive idéias mirabolantes quanto a isso. Você deve usar o mesmo script server-side tanto para requisições assíncronas (Ajax) quanto para as síncronas (me refiro àquelas via browser). Para isso, usamos aquele header <code>X-Requested-With</code>, que seu server-side deve identificar.</p>
<p>Dessa maneira, não &#8220;trancamos&#8221; o conteúdo nem ao usuário nem aos buscadores e afins. Benefícios ao usuário e a você (e ao seu bolso, se for o caso).</p>
<p>Lembre-se de tornar o conteúdo Ajax-less atrativo aos olhos do usuário também, usando o mesmo layout do resto da aplicação (ou a mesma estrutura, caso seja XML).</p>
<h3>Desempenho</h3>
<p>O desempenho é outra característica muito essencial. Em tráfego de dados muito grande, devemos tomar cuidado com o JavaScript. Muito <a title="responseXML" href="http://juliogreff.net/responsexml/">XML</a> gera muitas chamadas ao DOM, e isso leva tempo. Aí o <a title="JavaScript Object Notation" href="http://juliogreff.net/javascript-object-notation/">JSON</a> entra em cena.</p>
<p>O Profiler do Firebug pode ser muito útil, já que ele monitora o tempo de execução da sua aplicação e das requisições que ela faz.</p>
<p>Bem, é isso. Quem sabe um dia veremos uma aplicação destas. Estou trabalhando em uma função que faça boa parte disso, espero que consiga terminar. Fui!</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/hijax-ajax-acessivel/' rel='bookmark' title='Permanent Link: Hijax: Ajax Acessível'>Hijax: Ajax Acessível</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-vs-moda-vs-performance/' rel='bookmark' title='Permanent Link: Ajax vs. Moda vs. Performance'>Ajax vs. Moda vs. Performance</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/a-aplicacao-ajax-perfeita/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Histórico para Navegação via JavaScript</title>
		<link>http://juliogreff.net/historico-para-navegacao-via-javascript/</link>
		<comments>http://juliogreff.net/historico-para-navegacao-via-javascript/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 23:03:34 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Destaques]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[botão voltar]]></category>
		<category><![CDATA[cross browser]]></category>
		<category><![CDATA[histórico]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/historico-para-navegacao-via-javascript/</guid>
		<description><![CDATA[Já foram criadas muitas soluções para consertar o histórico quando fazemos a navegação via JavaScript (o maior problema com Ajax): a do Cau Guanabara, a minha, a do Bermonruf, além de outras derivações juntando pedaços das três. Agora eu volto aqui não para criar uma função nova, mas sim explicar os passos para você criar [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/estatisticas-para-navegacao-via-javascript/' rel='bookmark' title='Permanent Link: Estatísticas para Navegação via JavaScript'>Estatísticas para Navegação via JavaScript</a></li>
<li><a href='http://juliogreff.net/botao-voltar-para-ie/' rel='bookmark' title='Permanent Link: Botão Voltar para IE'>Botão Voltar para IE</a></li>
<li><a href='http://juliogreff.net/ativando-o-botao-voltar/' rel='bookmark' title='Permanent Link: Ativando o Botão Voltar'>Ativando o Botão Voltar</a></li>
<li><a href='http://juliogreff.net/inneroptions/' rel='bookmark' title='Permanent Link: innerOptions'>innerOptions</a></li>
<li><a href='http://juliogreff.net/back-button-improved/' rel='bookmark' title='Permanent Link: Back Button Improved!'>Back Button Improved!</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Já foram criadas muitas soluções para consertar o histórico quando fazemos a navegação via JavaScript (o maior problema com Ajax): <a href="http://cauguanabara.blogsome.com" rel="external" title="Cau Guanabara">a do Cau Guanabara</a>, <a href="http://juliogreff.net/back-button-improved/" title="Back Button Improved">a minha</a>, <a href="http://bermonruf.wordpress.com/2006/11/24/solucao-simples-para-o-botao-voltar-cross-browser/" rel="friend external" title="Solução Simples para o Botão Voltar Cross Browser">a do Bermonruf</a>, além de outras derivações juntando pedaços das três. Agora eu volto aqui não para criar uma função nova, mas sim explicar os passos para você criar a sua própria função, atendendo às suas próprias necessidades.</p>
<p>Vamos resolver o problema por partes, na seguinte ordem:</p>
<ul>
<li><a href="#bookmarking">Bookmarking</a></li>
<li><a href="#historico">Histórico</a></li>
<li><a href="#correcoes-ie">Correções para o IE</a></li>
<li><a href="#aperfeicoamentos">Aperfeiçoamentos</a></li>
<li><a href="#completo">Código Completo e Uso</a></li>
</ul>
<p>Vale lembrar também que estou escrevendo códigos para cuidar do histórico para <strong>JavaScript</strong>, e não só Ajax (aliás, todas as soluções anteriores faziam isso, mas pouca gente se tocou).</p>
<h3>Código Base</h3>
<p>Usaremos a seguinte página-base para testarmos nosso script:</p>
<pre><code>&lt;html&gt;
&lt;head&gt;
&lt;title&gt;BackButton Fixes&lt;/title&gt;
&lt;script&gt;
var appHash = ""; // Não se preocupe com essa linha agora...
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;select id="select"&gt;
&lt;option value="option-0"&gt;-- Change --&lt;/option&gt;
&lt;option value="option-1"&gt;Option 1&lt;/option&gt;
&lt;option value="option-2"&gt;Option 2&lt;/option&gt;
&lt;/select&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Como testaremos a navegação somente com JavaScript, não precisaremos fazer qualquer requisição Ajax. Portanto, não precisaremos de uma função para tal.</p>
<h3><a title="bookmarking" name="bookmarking"></a>Bookmarking</h3>
<p>Como na navegação via JavaScript não mudamos a URL, não podemos fazer bookmarking, já que a aplicação, sempre que acessada, estará no estado inicial. A única maneira de permitir o bookmarking seria mudando a URL.</p>
<p>Como sempre estaremos na mesma página, acrescentaremos apenas um fragmento após o nome do arquivo. Poderíamos optar pelas query strings (<code>file.ext?param=value</code>), mas elas atualizariam a página quando fossem mudadas. Então optaremos pelos hashes (<code>file.ext#hash</code>), que não atualizam a página e podem ser mudados à vontade.</p>
<p>Primeiramente, quando a página é carregada, precisamos verificar se houve bookmarking:</p>
<pre><code>function initialize() {
  var browserHash = window.location.hash.substring(1); // Hash da barra de navegação
  browserHash = (!browserHash) ? 0 : browserHash; // Hash padrão
  $("select").selectedIndex = browserHash;
}
</code></pre>
<p>Não se esqueça de modificar a tag body para <code>&lt;body onload="initialize()"&gt;</code> (nos preocuparemos com obstrusão depois), e de criar a função <code>$()</code> para pegar elementos pela ID.</p>
<p>Se especificarmos um hash &#8220;1&#8243; ou &#8220;2&#8243;, nosso select mudará quando <strong>atualizarmos</strong> a página, ele não mudará automaticamente. Mas já temos nosso bookmarking inicial.</p>
<p>Por enquanto, quando mudamos nosso select, a URL não muda. Isso significa que nosso usuário terá que adivinhar qual hash deverá usar, o que não é bom. Precisamos de uma função que mude o hash do navegador quando mudarmos as opções do select:</p>
<pre><code>function makeBookmark() {
  window.location.hash = "#" + $("select").selectedIndex; // Muda o hash da página
}
</code></pre>
<p>E também devemos modificar nosso select para <code>&lt;select id="select" onchange="makeBookmark()"&gt;</code>. Agora, toda vez que trocamos as opções do select, o hash do navegador muda para podermos fazer o bookmark mais tarde.</p>
<p>Até o presente momento, tudo funcionando no IE, no FF e no Opera. Note que no FF e Opera o histórico já é ativado, embora não faça efeito.</p>
<h3><a title="historico" name="historico"></a>Histórico</h3>
<p>Atualmente, os browsers não disparam evento algum quando voltamos ou avançamos no histórico. Sendo assim, não existe nenhuma maneira &#8220;automática&#8221; que nos ajude a verificar quando navegarmos pelo histórico.</p>
<p>Para fazer a verificação, executamos uma função em um curto intervalo de tempo. Essa função verifica se o hash do browser se refere ao estado da aplicação. Se for falso, faz as modificações necessárias.</p>
<p>Vamos começar fazendo as alterações necessárias para a função <code>initialize</code>:</p>
<pre><code>function initialize() {
  handleHistory(); // Verificação inicial
  window.setInterval(handleHistory, 100); // Intervalo para verificação
}</code></pre>
<p>Essa é a função que faz a verificação inicial e &#8220;agenda&#8221; as próximas, a cada 100 milissegundos. A função que faz a verificação é a seguinte:</p>
<pre><code>function handleHistory() {
  if(window.location.hash != appHash) { // Verificação de Estado
    appHash = window.location.hash; // Trocamos o estado da aplicação
    $("select").selectedIndex = window.location.hash.substring(1); // Trocamos a opção selecionada
  }
}
</code></pre>
<p>Ela compara o hash da aplicação (que é o <code>appHash</code>, variável global lá do início do nosso script) com o hash do browser. Se forem diferentes, faremos as adaptações, em nosso caso seria a mudança das opções do select.</p>
<p>Outra modificação necessária em nosso script será a função <code>makeBookmark</code>, que agora se chamará <code>makeHistory</code>:</p>
<pre><code>function makeHistory(newHash) {
  window.location.hash = "#" + newHash;
  appHash = newHash;
}
</code></pre>
<p>Ela será executada toda vez que mudarmos as opções do select. O select também deverá ser mudado para <code>&lt;select id="select" onchange="makeHistory(this.selectedIndex)"&gt;</code>.</p>
<p>Note que temos alguns problemas: quando no estado inicial, não temos diferença entre <code>appHash</code> e o hash do browser, fazendo com que nada aconteça (causa problemas com o uso de Ajax), e ainda não temos o funcionamento desejado nem no IE nem no Opera.</p>
<h3><a title="correcoes-ie" name="correcoes-ie"></a>Correções para o IE</h3>
<p>O IE sempre foi do contra, e ele não abriu excessão para nossa técnica anterior. Quando trocamos o hash da página, o IE não ativa o histórico, e não há maneira de contornar isso sem a gambiarra. Essa gambiarra seria o uso de um iframe escondido, do qual falaremos daqui a pouco.</p>
<p>Como você já deve ter entendido o espírito da coisa, vou postar o código inteiro, e vou explicando as linhas que forem necessárias, até porque alguém pode ter se perdido.</p>
<pre><code>var appHash = "";
var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") &gt; -1) ? true : false;
function $(id) { return document.getElementById(id); }
function makeHistory(newHash) {
  if(isIe === true)
    $("control-iframe").setAttribute("src", "control.htm?id=" + newHash);
  window.location.hash = "#" + newHash;
  appHash = newHash;
}
function handleHistory() {
  var browserHash = (hash = window.location.hash) ? hash : "#" + 1;
  if(browserHash != appHash) {
    appHash = browserHash;
    $("select").selectedIndex = browserHash.substring(1);
  }
}
function createIFrame() {
  var iFrame = document.createElement("iframe");
  iFrame.setAttribute("src", "control.htm?id=1");
  iFrame.setAttribute("id", "control-iframe");
  iFrame.style.display = "none";
  document.body.appendChild(iFrame);
}
function initialize() {
  if(isIe === true)
    createIFrame();
  handleHistory();
  window.setInterval(handleHistory, 100);
}
</code></pre>
<p>Vamos pela ordem. Na função <code>initialize</code>, criamos um iframe escondido se o browser for o IE (definido pela variável <code>isIe</code>, lá no começo), através da função <code>createIFrame</code>, sem mistério.</p>
<p>Na função <code>makeHistory</code>, trocamos a URL do iframe (se for o caso), forçando sua atualização (veremos porque mais tarde).</p>
<p>No iframe, temos o seguinte código:</p>
<pre><code>&lt;html&gt;&lt;head&gt;&lt;script type="text/javascript"&gt;
frameUrl = window.location.search.substring(4);
parentHash = (typeof(hash = parent.location.hash.substring(1)) != "undefined" ? hash : "");
if(frameUrl != "")
  parent.location.hash = frameUrl;
&lt;/script&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;
</code></pre>
<p>Toda vez que o iframe é atualizado (seja pelo usuário ou pela navegação no histórico), ele muda o hash da página pai, nos permitindo fazer a verificação de estados.</p>
<p>Também fiz uma pequena modificação: estado inicial (caso não haja um hash) para o FF/Opera. Na parte do IE já fiz direto.</p>
<h3><a title="aperfeicoamentos" name="aperfeicoamentos"></a>Aperfeiçoamentos</h3>
<p>Para facilitar o uso, e por causa de alguns bugs existentes, fiz algumas modificações no código ao longo do tempo. Não irei explica-las agora, isso fica para uma outra oportunidade.</p>
<p><a title="completo" name="completo"></a>O código completo do script, corrigido e atualizado, é esse:</p>
<pre><code>
var appHash = "";
var appIndex = "";
var appDefault = "home";
var appFunction = function(){};
var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") &gt; -1) ? true : false;
function $(id) { return document.getElementById(id); }
function makeHistory(newHash) {
  if(isIe === true)
    $("control-iframe").setAttribute("src", "control.htm?id=" + newHash);
  else if(newHash != appIndex)
    window.location.hash = newHash;
  else
    go2index();
}
function handleHistory() {
  var browserHash = (hash = window.location.href.split("#")[1]) ? hash : "";
  if(browserHash != appHash) {
    if(browserHash != "") {
      appFunction(browserHash);
      appHash = browserHash;
      makeHistory(browserHash);
	}
	else {
	  clearInterval(checkInterval);
	  window.location.hash = appHash;
	  makeHistory(appIndex);
	}
  }
}
function createIFrame() {
  var iFrame = document.createElement("iframe");
  iFrame.setAttribute("src", "control.htm?id=" + (hash = window.location.href.split("#")[1]) ? hash : appDefault);
  iFrame.setAttribute("id", "control-iframe");
  iFrame.style.display = "none";
  document.body.appendChild(iFrame);
}
function initialize() {
  if(isIe === true)
    createIFrame();
  checkBookmark();
  checkInterval = setInterval(handleHistory, 100);
}
function checkBookmark() {
  var browserHash = (hash = window.location.href.split("#")[1]) ? hash : "";
  window.location.hash = (browserHash == "") ? appDefault : browserHash;
}
function go2index() {
  window.location = window.location.href.split("#")[0] + "#";
  window.location.reload();
}
function goTo(strUrl) {
	window.location.hash = strUrl;
	appFunction(strUrl);
}
</code></pre>
<p>E o código do iframe control.htm é:</p>
<pre><code>&lt;html&gt;&lt;head&gt;&lt;script type="text/javascript"&gt;
frameUrl = window.location.search.substring(4);
parentHash = (typeof(hash = parent.location.href.split("#")[1]) != "undefined" ? hash : "");
if(parentHash != "" &amp;&amp; frameUrl == parent.window.appIndex)
  parent.window.go2Index();
else if(frameUrl != "" &amp;&amp; frameUrl != parent.window.appIndex)
  parent.location.hash = frameUrl;
&lt;/script&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;
</code></pre>
<p>Pra usar a função, você faz sua página normalmente. Você precisará criar um arquivo com todo o script acima, e inclui-lo em sua página. Você também precisará criar o arquivo control.htm, o nosso iframe.</p>
<p>No script, você poderá mudar as variáveis <code>appDefault</code> (hash inicial), <code>appIndex</code> (hash que deve atualizar a página) e <code>appFunction</code> (função que faz a navegação). Para executar sua função de navegação, chame a função <code>makeHistory</code>, passando a query string como parâmetro.</p>
<p>Simples, não? Não, mas é fácil de usar. Dúvidas, bugs, sugestões, qualquer coisa que possa ajudar, é só comentar!</p>
<h3>Créditos</h3>
<p>Não criei tudo isso do nada, me baseei em algumas idéias já existentes. As principais foram de Mike Stenhouse (idéia original), Bernardo Rufino (aperfeiçoamentos), Dekassegui (correções e personalizaçãoes), e um pouco da minha idéia quase-original também (que não me lembro o nome do sujeito que tinha postado um rascunho em um fórum por aí).</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/estatisticas-para-navegacao-via-javascript/' rel='bookmark' title='Permanent Link: Estatísticas para Navegação via JavaScript'>Estatísticas para Navegação via JavaScript</a></li>
<li><a href='http://juliogreff.net/botao-voltar-para-ie/' rel='bookmark' title='Permanent Link: Botão Voltar para IE'>Botão Voltar para IE</a></li>
<li><a href='http://juliogreff.net/ativando-o-botao-voltar/' rel='bookmark' title='Permanent Link: Ativando o Botão Voltar'>Ativando o Botão Voltar</a></li>
<li><a href='http://juliogreff.net/inneroptions/' rel='bookmark' title='Permanent Link: innerOptions'>innerOptions</a></li>
<li><a href='http://juliogreff.net/back-button-improved/' rel='bookmark' title='Permanent Link: Back Button Improved!'>Back Button Improved!</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/historico-para-navegacao-via-javascript/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Ajax vs. Moda vs. Performance</title>
		<link>http://juliogreff.net/ajax-vs-moda-vs-performance/</link>
		<comments>http://juliogreff.net/ajax-vs-moda-vs-performance/#comments</comments>
		<pubDate>Sun, 11 Mar 2007 16:24:31 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Usabilidade/Acessibilidade]]></category>
		<category><![CDATA[acessibilidade]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/?p=77</guid>
		<description><![CDATA[Lendo o Tableless, &#8220;Cuidado para não regredir&#8220;, continua a velha discussão sobre o que é bom, o que é moda e o que realmente não presta pra nada (esse último não é o caso de nenhum dos dois posts&#8230;). Vamos à uma discussão rapidinha. Pense: vale a pena escrever uma montanha de código JavaScript, correndo [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/hijax-ajax-acessivel/' rel='bookmark' title='Permanent Link: Hijax: Ajax Acessível'>Hijax: Ajax Acessível</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Lendo o <a title="Tableless" rel="external" href="http://www.tableless.com.br">Tableless</a>, &#8220;<a title="Cuidado para não regredir" rel="external" href="http://www.tableless.com.br/cuidado-para-nao-regredir">Cuidado para não regredir</a>&#8220;, continua a velha discussão sobre o que é bom, o que é moda e o que realmente não presta pra nada (esse último não é o caso de nenhum dos dois posts&#8230;).</p>
<p>Vamos à uma discussão rapidinha. Pense: vale a pena escrever uma montanha de código JavaScript, correndo o risco de ficar completamente inacessível para alguns browsers, quebrar a cabeça, fazer algo bonitinho que demora o dobro pra carregar, sabendo que você podia escrever uma (uma só, nada mais, sem exagero) única linha? É o caso do pessoal que faz todos os links usando Ajax.</p>
<p>E não é só isso. Há muita coisa que poderia ser evitada. Carregar páginas quase inteiras, pequenos textos estáticos (babem&#8230;), outras coisinhas irritantes que pulam na tela&#8230; Quer que eu prove que não melhora a performance?  <a title="XML HTTP Performance and Caching" rel="external" href="http://me.eae.net/archive/2005/04/02/xml-http-performance-and-caching/">XML HTTP Performance and Caching</a>. Creio que posso te convencer.</p>
<p>Descartando a acessibilidade por enquanto. Um site que use Ajax, pra ser mais útil e mais rápido, precisa de muito planejamento. Um ótimo exemplo de planejamento é o Gmail e Google Reader. Inclua a acessibilidade: ainda temos o Google na frente (Gmail sem Ajax também existe). Uma <a title="As Verdadeiras Restrições do Ajax" rel="external" href="http://ajaxonline.com.br/forum/viewtopic.php?t=7">boa discussão</a> sobre isso também rolou lá no Ajax Online.</p>
<p>Apesar de tudo, ainda acredito que já evoluímos muito, e estamos evoluindo. O Ajax no Brasil já amadureceu bastante (até o Ajax Online abandonou a versão 100% Ajax, evolução). Ainda temos muito a progredir, e vai demorar, eu sei, mas não podemos parar. Graças a muita gente já temos trabalhos bons. Agora queremos trabalhos ótimos, basta amadurecer a idéia.</p>
<p>Esta é a minha opinião, não tomem como certa. Apenas pense sobre isso, concorde ou não. Até!</p>
<p class="post-see">Também já havia falado sobre essas algumas questões relacionadas a Ajax em <a href="http://juliogreff.net/ajax-vs-acessibilidade/" title="Ajax vs. Acessibilidade">Ajax vs. Acessibilidade</a>. Também falei sobre <a href="http://juliogreff.net/a-aplicacao-ajax-perfeita/" title="A Aplicação Ajax Perfeita">A Aplicação Ajax Perfeita</a>, que pode colocar algumas minhocas em sua cabeça&#8230;</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/hijax-ajax-acessivel/' rel='bookmark' title='Permanent Link: Hijax: Ajax Acessível'>Hijax: Ajax Acessível</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
<li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/ajax-vs-moda-vs-performance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ajax: Requisições HEAD</title>
		<link>http://juliogreff.net/ajax-requisicoes-head/</link>
		<comments>http://juliogreff.net/ajax-requisicoes-head/#comments</comments>
		<pubDate>Sat, 17 Feb 2007 21:34:04 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/?p=65</guid>
		<description><![CDATA[É nóis di novo, apresentando mais um daqueles recursos que você vai achar extremamente interessante, mas não vai achar uso nenhum para ele. Falo das requisições to tipo HEAD em Ajax. Elas tem utilidade sim, mas você vai ter que por a cabeça pra pensar pra conseguir achar alguma. O que é uma requisição HEAD? [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-sem-o-x/' rel='bookmark' title='Permanent Link: Ajax sem o X'>Ajax sem o X</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>É nóis di novo, apresentando mais um daqueles recursos que você vai achar extremamente interessante, mas não vai achar uso nenhum para ele. Falo das requisições to tipo HEAD em Ajax. Elas tem utilidade sim, mas você vai ter que por a cabeça pra pensar pra conseguir achar alguma.</p>
<h3>O que é uma requisição HEAD?</h3>
<p>Em uma requisição do tipo HEAD, oição do tipo HEAD, o servidor apenas retorna as linhas de cabeçaletorna as linhas de cabeçalho (os headers) de um arquivo qualquer. Isso quer dizer que podemos descobso quer dizer que podemos descobrir o Content-Type, ou Last-Modified de um arquivo sem precisar receber todo ele.<br />
Qual é a utilidade disso tudo? Não muita, concordo. Mas pense. Temos um arquivo extremamente grande para ser retornado. Devemos atualizar ele a um certo tempo, mas não precisamos disso se sua última modificação foi antes da primeira requisição. Fazemos uma requisição HEAD, descobrimos isso, e retornamos tudo aquilo apenas se precisarmos. Redundante, pouco prático, mas ainda assim é útil.</p>
<h3>Fazendo a tal requisição</h3>
<p>Para fazermos a &#8220;tal requisição&#8221;, precisamos de um objeto <code>XMLHttpRequest</code> já setado. Mas antes de colocar a mão na massa, veja o que pode ser o cabeçalho de um arquivo:</p>
<pre><code>HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Cache-Control: max-age=172800
Expires: Sat, 06 Apr 2002 11:34:01 GMT
Date: Thu, 04 Apr 2002 11:34:01 GMT
Content-Type: text/html
Accept-Ranges: bytes
Last-Modified: Thu, 14 Mar 2002 12:06:30 GMT
ETag: "0a7ccac50cbc11:1aad"
Content-Length: 52282</code></pre>
<p>Veja bem: você conhece (e talvez usou, em Ajax mesmo) alguns desses headers. Até creio que seja possível retorna-los mesmo em uma requisição GET ou POST, mas não vem ao caso.<br />
Para retornarmos um header individual, utilizamos o método <code>getResponseHeader(strName)</code>, e para retornarmos todos os headers podemos usar <code>getAllResponseHeaders()</code>. Um exemplo mais prático:</p>
<pre><code>// Eis o mistério resolvido
xmlhttp.open("HEAD", "http://qualquer.lugar.com", false);
// Usei uma requisição síncrona, pra não precisar tratar dos readyStates
xmlhttp.send("");
alert(xmlhttp.getAllResponseHeaders());</code></pre>
<p>Facinho, não? Eu disse, o difícil é achar utilidade, mas se você tem uma mente engenhosa ou estilo dominador-global-ou-genérico-maluco, você vai achar&#8230;</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/fila-de-requisicoes-em-ajax/' rel='bookmark' title='Permanent Link: Fila de Requisições em Ajax'>Fila de Requisições em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-sem-o-x/' rel='bookmark' title='Permanent Link: Ajax sem o X'>Ajax sem o X</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/ajax-requisicoes-head/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fila de Requisições em Ajax</title>
		<link>http://juliogreff.net/fila-de-requisicoes-em-ajax/</link>
		<comments>http://juliogreff.net/fila-de-requisicoes-em-ajax/#comments</comments>
		<pubDate>Fri, 16 Feb 2007 21:30:56 +0000</pubDate>
		<dc:creator>Julio Greff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[boas práticas]]></category>

		<guid isPermaLink="false">http://www.juliogreff.blog.br/?p=63</guid>
		<description><![CDATA[O Ajax está amadurecendo. Hoje já se vê aplicações bem pensadas, onde deveriam estar. Sempre tem o pessoal que abusa, mas já diminuiu muito. Estamos caminhando na direção certa. Já faz um certo tempo que não falo nesse assunto, mas hoje estou de volta, nem que seja só por agora. Vamos ver como fazer um [...]

<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>O Ajax está amadurecendo. Hoje já se vê aplicações bem pensadas, onde deveriam estar. Sempre tem o pessoal que abusa, mas já diminuiu muito. Estamos caminhando na direção certa.<br />
Já faz um certo tempo que não falo nesse assunto, mas hoje estou de volta, nem que seja só por agora. Vamos ver como fazer um fila de requisições, pra que todas sejam completadas sem interferência.</p>
<h3>Preparação</h3>
<p>A fila de requisições baseia-se em uma variável (lógico). Usaremos um simples array:</p>
<pre><code>var fila = new Array();
</code></pre>
<p>Precisaremos também de duas funções, uma que coloca a requisição na fila, e outra que executa a fila em ordem.</p>
<h3>Colocando na Fila</h3>
<p>Para colocarmos um item na fila, usaremos a função <code>queueAjax</code>, descrita abaixo.</p>
<pre><code>var queueAjax = function(id, url) {
  // Usando o id, você pode colocar um carregando:
  document.getElementById(id).innerHTML = "Carregando...";
  // Adicionando nossa requisição:
  fila.push([id, url]);
  // Não tendo requisições pendentes, lançamos outra função
  if(fila.length &gt; 1) executeQueue();
}</code></pre>
<p>Analisando: colocamos <code>id</code> e <code>url</code> na fila, de uma forma ou outra. Se não houverem mais que uma requisição na fila, executamos a função <code>executeQueue()</code> (sem argumentos mesmo). Ela se encarregará de todo o resto.</p>
<h3>Executando cada Requisição&#8230;</h3>
<p>Não precisaremos executar cada requisição manualmente (lógico, a fila é pra isso). Usaremos a função <code>executeQueue()</code> pra isso. Neste momento, estou assumindo que você tem a variável <code>xmlhttp</code> configurada como um objeto <code>XMLHttpRequest</code>.</p>
<pre><code>var executeQueue = function() {
  var current = fila.shift(); // Retiramos o primeiro membro do array
  xmlhttp.open("GET", current[1], true);
  xmlhttp.onreadystatechange = function() {
    // Aqui você cuida dos readyStates
    // Quando for 4: (não coloquei o código, poupando espaço)
    document.getElementById(current[0]).innerHTML = xmlhttp.responseText;
    // Tá pronto, e passamos ao próximo item, se houver
</code><code>    if(fila.length &gt; 0) setTimeout(executeQueue, 100);
</code><code>  }
  xmlhttp.send(null);
}
</code></pre>
<p>Analisando de novo: fazemos nossa requisição como sempre (poupei código, também pra prevenir Ctrl + C e V). Note que tiramos o primeiro item do array, e colocamos em uma variável.<br />
Quando a nossa requisição atual estiver prontinha, e o resultado no lugar, podemos executar a próxima (se houver), sem que precisemos fazer nada.</p>
<h3>Usando tudo isso</h3>
<p>Pra usar você só vai precisar chamar uma função: <code>queueAjax(id, url)</code>, pra cada requisição que você quiser fazer. Nada mais.<br />
Você também pode estender muito mais esse script, colocando opções, tratamento para as saídas&#8230; Dê asas a sua criatividade.</p>


<h3>Posts Relacionados</h3><ul><li><a href='http://juliogreff.net/ajax-requisicoes-head/' rel='bookmark' title='Permanent Link: Ajax: Requisições HEAD'>Ajax: Requisições HEAD</a></li>
<li><a href='http://juliogreff.net/utilizando-o-metodo-post/' rel='bookmark' title='Permanent Link: Utilizando o Método POST em Ajax'>Utilizando o Método POST em Ajax</a></li>
<li><a href='http://juliogreff.net/ajax-com-a-mootools/' rel='bookmark' title='Permanent Link: Ajax com a Mootools'>Ajax com a Mootools</a></li>
<li><a href='http://juliogreff.net/ajax-vs-acessibilidade/' rel='bookmark' title='Permanent Link: Ajax vs. Acessibilidade'>Ajax vs. Acessibilidade</a></li>
<li><a href='http://juliogreff.net/a-aplicacao-ajax-perfeita/' rel='bookmark' title='Permanent Link: A Aplicação Ajax Perfeita'>A Aplicação Ajax Perfeita</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://juliogreff.net/fila-de-requisicoes-em-ajax/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

