Cada día son más frecuentes las aplicaciones web que hace un uso extensivo de JavaScript, relegando una mayor carga computacional al cliente, dentro de la arquitectura cliente-servidor, lo que habitualmente se conoce como cliente pesado. Con ello, entre otras cosas, se logra una interfaz de usuario mucho mas rica en prestaciones.

Algunos ejemplos de webs que hacen uso de esto es el cliente de correo de Google Gmail, o las famosas redes sociales como Facebook o Tuenti. En estas aplicaciones, toda la interfaz está gobernada por JavaScript. Cuando accedemos a un enlace, generalmente no conlleva una nueva petición HTTP sino que, en su lugar, el documento actual se actualiza con nuevo contenido (AJAX).

Pero existe un inconveniente: Al hacer las webs así, no se almacenan las actualizaciones de la página en el historial del navegador, de modo que los botones de volver y avanzar del navegador no funcionan como esperaríamos. Esto ocurre porque la URL no ha cambiado, y por tanto, para el navegador no ha habido ningún cambio de página.

Pero en Facebook o GMail, pese a funcionar con JavaScript, sí funciona el botón de volver. ¿Cómo lo hacen? La magia está en el caracter almohadilla (#). Repasemos HTML: Cuando en un documento queremos hacer un enlace a una parte del mismo (Por ejemplo, para saltar a un apartado), lo hacemos con el caracter almohadilla seguido de la palabra clave. Por ejemplo:

<h1 id="top">Inicio</h1>
<p>Un párrafo con mucho contenido...</p>
<a href="#top">Volver arriba</a>

Una de las ventajas de estos enlaces es que no conllevan una nueva petición HTTP, por lo que son inmediatos. Además, el navegador tiene constancia de ellos, por lo que los almacena en el historial. Bien, pues ahí está el truco. Si nos fijamos en una URL de Facebook, veremos que son de este tipo:

http://www.facebook.com/#!/?sk=messages&filter=[fb]unread

Es decir, en este caso el enlace es a la página principal (http://www.facebook.com/) y dentro de ese documento, a un apartado (#!/?sk=messages&filter=[fb]unread). Con JavaScript podemos consultar ese apartado para, en función de él, cargar el contenido que proceda. Ya tenemos todas las piezas para hacer una aplicación web en JavaScript, donde funcionará el historial del navegador, y además podremos guardar las URLs en nuestros marcadores.

Acerca del evento hashchange

Para poder realizar eso, necesitamos un método para que, desde JavaScript, sepamos cuándo se ha actualizado el historial #hash, es decir, para saber cuándo se enlaza a otro apartado dentro del documento actual. En HTML5 queda resuelto esto con el evento windows.onhashchange. Sin embargo, al ser un evento nuevo, no está disponible en todos los navegadores, por lo que se hacen necesarios algunos hacks que permitan que nuestra aplicación funcione en la mayoría de navegadores.

En el caso de utilizar jQuery, el plugin más extendido es jQuery BBQ. Podemos leer más acerca de cómo funciona aqui:
http://benalman.com/projects/jquery-hashchange-plugin/

Implementación básica en jQuery

Este ejemplo es muy sencillo. Únicamente tendremos una lista de enlaces, y marcaremos en negrita al activo, y mostraremos su contenido. Entendiendo eso, podremos aplicarlo a todo lo demás.

En primer lugar, necesitaríamos incluir la biblioteca jquery, y además también el plugin de jquery BBQ.

<!DOCTYPE html>
<html lang="es">
<head>
<script type="text/javascript" src="jquery-1.4.1.js"></script>
<script type="text/javascript" src="jquery.ba-bbq.js"></script>
</head>
<body>
</body>
</html>

Después definimos una lista de enlaces y sus bloques de contenido:

<ul>
    <a href="#enlace1">Enlace 1</a>
    <a href="#enlace2">Enlace 2</a>
    <a href="#enlace3">Enlace 3</a>
    <a href="#enlace4">Enlace 4</a>
</ul>
<div id="enlaces">
    <div id="enlace1">Contenido Enlace 1</div>
    <div id="enlace2">Contenido Enlace 2</div>
    <div id="enlace3">Contenido Enlace 3</div>
    <div id="enlace4">Contenido Enlace 4</div>
</div>

Y ahora el código JavaScript:

$(function(){
  $(window).bind('hashchange', function(e) {
    var url = $.param.fragment();
    $('a.current').removeClass('current');
    if (url) {
        $('a[href="#' + url + '"]').addClass( 'current' );
        $("#enlaces > div").hide();
        $("#"+url).show();
    }
  });

  $(window).trigger( 'hashchange' );

});

El código hace lo siguiente:

  1. En primer lugar definimos una función que irá atada al evento ‘hashchange’. Este evento se dispara, como hemos visto, cada vez que se actualiza el #hash.
  2. En segundo lugar, consultamos el parámetro #hash y lo almacenamos en la variable ‘url’.
  3. Desactivamos el enlace previamente activo.
  4. En caso de que esté definido el parámetro #hash:
    1. Activamos el nuevo enlace activo. Tan sólo le añadimos una clase.
    2. Ocultamos todos los bloques de contenido.
    3. Mostramos el bloque de contenido activo.
  5. Lanzamos el evento hashchange para provocar una actualización, por si en la primera carga de la página ya hubiera un parámetro #hash (Por ejemplo, porque alguien ha guardado una URL en favoritos).

Finalmente, definimos el estilo para la clase “current” y ya lo tenemos.

Podéis probar una demo. Como veis, tras moverte entre los distintos apartados, los botones de Volver y Avance del navegador funcionan. Además, se pueden almacenar las URLs para su futura consulta.