Ajax com Javascript não intrusivo (unobtrusive Ajax)

{lang: 'pt-BR'}

O que é javascript não intrusivo?

Quando criamos nossas páginas HTML, repletas de javascript, estamos sujeitos a espalhar trechos de código por diversos elementos da página, como botões, links, imagens etc. Esta é uma prática bastante comum e muito ruim, pois dificulta muito a manutenção e reuso do código gerado. O javascript não intrusivo (unobtrusive javascript) sugere que o código HTML fique separado do código javascript, trazendo organização, modularidade, e maior facilidade na criação de plugins. Ao invés de adicionarmos códigos javascript aos eventos diretamente nos elementos HTML, construimos um HTML mais simples, e adicionamos um código javascript que irá observar quando o evento for disparado.

Ao invés de fazermos isso:

<script>
   function exibeResultado(){
       // faz alguma coisa ...
   }
</script>

<button onclick="exibeResultado()">Exibir</button>

Fazemos isso:

<script>
    // Quando a página for carregada
    $(function(){
         $("#btnExibir").click(function(){
               // faz alguma coisa ...
         }
     }
</script>
<button id="btnExibir">Exibir</button>

Neste exemplo, fazendo uso da biblioteca jQuery para definir o comportamento do clique do botão quando a página for totalmente carregada.

Esta estratégia é especialmente útil quando lidamos com páginas que serão exibidas em diferentes navegadores. Se um determinado navegador não possui uma certa funcionalidade, o nosso Javascript simplesmente falha, mas o usuário ainda será capaz de ver o conteúdo original.

Um bom exemplo desta técnica, é o framework Lightbox 2 para exibir fotos na forma de um album. Par ausá-lo basta criar um link para a foto original e avisar ao lightbox que aquela foto será exibida através do atributo rel="lightbox" no link. Algo como:

<a href="images/foto1.jpg" rel="lightbox" title="Viagem para Porto de galinhas">Foto da viagem</a>

Se o Lightbox não funcionar, o usuário ainda será capaz de clicar no link e abrir a foto em outra página.

Para que um link vire uma chamada ajax devemos proceder da mesma maneira, via Javascript trocamos o comportamento padrão por uma chamada ajax. Entretanto, só isso não basta. É preciso dizer ao browser que precisamos remover a ação de mudar de página quando o link for clickado.

<script>

    // Extrai o postID da url de um link
    function extractPostID(url){
var token = "postID="
var posToken = url.indexOf(token);
var postID = url.substring(posToken + token.length);
return postID;
} // Carrega o post via Ajax function loadPost(postID){ // Faz Carrega o conteúdo da chamada ajax no elemento com id "post" $("#post").load("post.php?postID="+postID, function(){ // Ao terminar a chamada ajax, redefinir o comportamento dos botões setNavHandler(); });, }  // Cancela o comportamento padrão de um click em um link function preventDefault(e){ if( e.preventDefault ) { e.preventDefault(); } e.returnValue = false; if (e.stopPropagation) e.stopPropagation(); // DOM Level 2 else e.cancelBubble = true; // IE }  // Substitui o redirecionamento de um link para uma chamada Ajax function btnNavClickHandler(e){ if (!e) e = window.event; // IE event model // Obtém o endereço do link var target; if (e.target) target = e.target; else if (e.srcElement) target = e.srcElement; else if (target.nodeType == 3) target = target.parentNode; // defeat Safari bug preventDefault(e); var postID = extractPostID(target.href); loadPost(postID); } // Define uma ação para os botões de próximo e anterior function setNavHandler(){ $("#btnNext").click(btnNavClickHandler); $("#btnPrev").click(btnNavClickHandler);  }   // Quando a página é carregada   $(function(){ setNavHandler() }); </script> <div id="post"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed enim velit, pretium at volutpat vitae, volutpat at augue. Nullam tempus, urna id gravida vestibulum, enim urna sodales tortor, in pulvinar nisi eros pretium est.</p> <a id="btnPrev" href="post.php?postID=1">Post Anterior</a> <a id="btnNext" href="post.php?postID=3">Próximo Post</a> </div>

O exemplo acima representa uma página com um post. Ao clicar nos botões de próximo ou anterior, o usuário seria redirecionado para uma outra página, porém, alteramos este comportamento para que uma chamada Ajax seja feita, e o resultado substitua o conteúdo da página.

Repare que cancelamos o comportamento padrão do link criando um método genérico  preventDefault(), que engloba rotinas específicas para cada browser. Este é o “pulo do gato” do Ajax não-intrusivo, pois sem isto, o link continuaria funcionando e, mesmo que o Ajax fosse executado, ele não iria impedir que a página fosse redirecionada.

Exemplo com suporte a botão de back e histórico: unobstrusive-ajax
Não abordei o controle de histórico neste artigo para mantê-lo mais simples.

Código fonte do exemplo (incluindo os arquivos PHP):  unobtrusive-ajax.zip.

{lang: 'pt-BR'}
  • Ved

    =D Obrigado por postar!