sistema de rutas con javaScript

Cómo armar un sistema de rutas en una single page application con javaScript

Silvia Goytia

archivado en: JavaScript / 1 octubre, 2014

window.location es una propiedad del objeto window de javaScript muy útil y que hace referencia a la localización del documento, a la dirección url para entendernos. Entre otros datos nos indica el nombre de dominio (window.location.hostname) o la url en la que nos encontramos (window.location.href) y entre esos datos hay uno del que hablaré hoy: hash, que nos da todo lo que sigue a la almohadilla (#). Por ejemplo, si estuviéramos en esta url:

www.soyunadireccion#soyunhash

esto:

console.log(window.location.hash);

nos daría soyunhash.

Suavizando el scroll

Un ejemplo de las posibilidades de location.hash nos lo da el scroll de los anchor / name. En vez de dejar que estos enlaces internos funcionen de su forma habitual, saltando de golpe de un sitio a otro de la página, podemos interceptar su comportamiento y poner una transición más suave con jQuery. Por ejemplo, si tenemos esto en el html:

<a href="#abajo">Para abajo</a>

<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br />

<p><a id="abajo"> Hey!</a></p>

</body>

Podríamos hacer algo así:

$(document).ready(function() {

$('a[href^="#"]').click(function(event) {

event.preventDefault();

window.location.hash = "#";

var target = this.hash,

/* Si se usa name en vez de un id, cambiar el selector, claro */

$target = $(target);

$('html, body').stop().animate({

'scrollTop': $target.offset().top

}, 3000, 'swing', function() {

window.location.hash = target;

});

});

});

Rutas con location.hash

Pero aún más chulo es lo que podemos hacer con location.hash y las rutas, al menos si estamos haciendo una spa (single page application), ya que podemos leer la ruta y redireccionar hacia un escenario u otro... algo parecido a esto:

En la URL nos llega un ítem...

www.bichos.com#trasgos

... que cazamos para ir a un sitio u otro.

<body onload="function init()">

...

function init() {

var direccion = window.location.hash;

if ( direccion != "" ) {

// pintamos la página que muestra un bicho en concreto

pintaBichos(direccion);

} else {

// pintamos la portada

pintaPortada();

}

}

Rutas con pushState()

El ruteo anterior podríamos hacerlo de otra forma con window.location.href y un split si es muy simple o una expresión regular si fuera más complejo.

var direccion = window.location.href.split('/');

var bicho = direccion.pop();

Así podríamos utilizar urls más elegantes o amigables que esa miserable almohadilla, como una barra inclinada de lo más moderna o lo que nos apetezca. Ahora bien, este método nos plantea dos problemas: ¿Cómo hacer que no dé un error 404, página no encontrada, al poner una url? y, dos, ¿cómo hacer que las urls sean persistentes?

El primer problema lo podemos resolver trasteando con el .haccess si nuestro servidor corre bajo Apache, que suele ser lo habitual. Así, basta con indicar que sea cual sea la dirección escrita en el navegador, cargue index.html, la puerta de acceso a nuestra spa (ver explicación de Joss Crowcroft).

<ifModule mod_rewrite.c>

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_URI} !index

RewriteRule (.*) index.html [L]

</ifModule>

Vamos ahora a resolver el segundo y, de paso, controlar los botones de atrás y adelante del navegador cuando un usuario está en nuestra página.

Cada vez que visitamos una web, el navegador la almacena en caché y la guarda en su historial. Es como si guardara en su agenda un par de clave/valor, con este "nombre", está asociada esta "dirección".  Esta agenda es el objeto history, el cual tiene cinco métodos y dos propiedades. Una de ellas es la propiedad history.length, que nos indica cuántos registros tiene anotados y la otra es history.state, que indica el nombre de la dirección, la clave (no es exactamente así, pero para aclararnos).

Entre los métodos hay tres que vienen de antiguo, que son:

  • history.back(): para cargar una dirección anterior;
  • history.forward(): para ir hacia delante;
  • history.go(): para ir a una en concreto.

Y hay dos que han llegado con HTML5, que son los que nos interesan ahora: history.pushState() y history.replaceState().

history.pushState() sirve para modificar la url que se muestra en la barra de navegación y para añadir un nuevo registro en el historial del navegador. Recibe tres parámetros: el nombre que le damos a ese registro (que debe ser un JSON), el título (que no vale para nada en la práctica) y la url asociada. Así, por ejemplo, si ponemos esto nada más cargar la página añadimos tres registros al historial:

var stateObj = { ubicacion: "miAplicacion" };

history.pushState(stateObj, "nombre de mi aplicación", "bienvenido.html");

history.pushState(stateObj, "nombre de mi aplicación", "bienvenido2.html");

history.pushState(stateObj, "nombre de mi aplicación", "bienvenido3.html");

En la barra de la url se ve bienvenido3.html y si un usuario le da al botón retroceder, verá bienvenido2.html y si le vuelve a dar bienvenido.html.

Así, podemos armar una barra de navegación:

<div id="enlace1">Portada</div>

<div id="enlace2">ver elfos</div>

Y luego modificar la dirección de la url y el registro del historial:

$('#enlace1').click(function() {

history.pushState(stateObj, "nombre de mi aplicación", "index.html");

pintaPortada();

});

$('#enlace2').click(function() {

history.pushState(stateObj, "nombre de mi aplicación", "index/elfos.html");

pintaBichos('elfos');

});

(replace.state funciona igual, pero modifica el valor en vez de añadir uno nuevo).

Ya está casi todo listo, lo único que nos falta es detectar el momento en que el usuario le da a los botones atrás y adelante del navegador. Y para eso contamos con un método de window: onpopstate.

window.onpopstate = function(event) {

// Aquí mandamos pintar un escenario u otro según corresponda después de leer dónde nos encontramos con document.location

};

Chulo, ¿no?

|| Tags: , ,

valoración de los lectores sobre sistema de rutas con javaScript

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 5 sobre 5 (3 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.