> Manuales > Taller de Javascript

Cómo detectar que el usuario ha hecho una navegación interna en la página web, cambiando el hash (lo que hay detrás de la almohadilla de la URL). Sería la base de un sistema de routing rudimentario para una SPA.

Detectar cambios en el hash de la URL con Javascript

En este artículo vamos a ver lo que podría ser el inicio de un sistema de routing, la base de funcionamiento que usan las SPA (Single Page Application). Sería la base de una funcionalidad de routing rudimentaria en Javascript, los más primarios, en los que se usaba simplemente el hash de la URL. Nuestro objetivo es enseñar la parte de la detección de cambios en el hash.

Qué es el hash de la URL

Lo que se conoce como hash en la URL es lo que hay después de la almohadilla (que se llama gato o numeral en otras regiones). Esta parte de la URL es la que se utiliza para realizar enlaces internos, que funcionan dentro de la misma página. Seguramente ya los conozcas del propio HTML.

Por ejemplo podríamos tener una URL como esta, que tiene su hash:

example.com#contacto

En la URL anterior la palabra contacto sería el hash.

Por qué querríamos detectar lo que hay en el hash

En los sitios web el hash se utiliza simplemente para conseguir enlaces internos dentro de la misma página. Generalmente no tienes que detectar nada con JavaScript cuando los usas con HTML, pero en las aplicaciones web estos hash pueden formar parte esencial de la navegación, especialmente en los sitios del modelo "single page application".

Los sitios de navegación por una única página pueden usar distintos mecanismos para conseguir que, al pulsar los enlaces, el navegador intercambie la vista y muestre otro contenido sin refrescar la página. El Hash sería simplemente el más primitivo pero que te asegura que el routing funcione en cualquier navegador y sobre cualquier configuración de servidor web.

Esta funcionalidad se basa en que, al manipular el hash, no se produce navegación a otra página. Sin embargo mediante javascript sí que somos capaces de detectar ese cambio y producir el comportamiento necesario, para que el contenido de la página se modifique al pulsar enlaces con su hash, con lo cual conseguimos el efecto de las SPA.

Además, los cambios de hash producen también nuevas entradas en el historial, lo que permite que el usuario pueda utilizar los botones de adelante y atrás del navegador para moverse entre las distintas pantallas de la aplicación web. Esta misma característica hace que se puedan almacenar enlaces a pantallas internas de la aplicación en favoritos.

Cómo detectar el hash con Javascript

Para detectar el valor que hay en el hash de la URL mediante javascript utilizamos el objeto location. En un artículo anterior ya explicamos con mucho detalle que ofrece este objeto y cómo utilizarlo, por lo que os dejo el enlace aquí: Objeto location del navegador.

Para acceder a lo que hay detrás de la almohadilla de la URL necesitamos simplemente acceder a la propiedad hash del objeto location. Por ejemplo con un código como este:

let hashValue = window.location.hash;

Cómo detectar cambios del hash mediante Javascript

La parte más interesante del trabajo con el hash consiste en la detección de los cambios en tiempo real que ocurren en la parte de la URL que va detrás de la almohadilla. Para conseguirlo utilizamos el evento hashchange de Javascript.

Este evento está disponible en el objeto window y lo podemos usar de esta manera:

// Agregar el manejador para el evento hashchange del objeto window
window.addEventListener("hashchange", onHashChange);

La función manejadora del evento podría ser como esta:

function onHashChange() {
    let hashValue = window.location.hash;
    console.log("Hash actual:", hashValue);
}

Gracias a la declaración de este manejador de evento, la función se ejecutará cada vez que cambie el fragmento (lo que hay después de la almohadilla o numeral) de la URL.

Cómo detectar el hash actual cuando la página se carga

Para controlar todas las situaciones donde tengamos un hash en la URL no nos vale simplemente con crear este manejador de evento, porque podría darse el caso de que la página tuviese ya un hash cuando se ha cargado por primera vez.

El manejador de evento asignado a hashchange sólo detecta los cambios que hayan posteriores a la carga de la página.

Con el código siguiente podríamos añadir un evento DOMContentLoaded, que nos permitiría invocar la función anterior también cuando la página esté lista para realizar acciones que manipulen su contenido en el DOM.

window.addEventListener("DOMContentLoaded", onHashChange);

Ejemplo completo de trabajo de detección de cambios en el hash

Con lo que hemos aprendido en este artículo vamos a mostrar ahora un ejemplo de una página web que es capaz de detectar cambios en el hash y mostrar sus valores en mensajes en la consola, para indicar en todo momento el hash actual.

En este ejemplo de página encontrarás diversos enlaces para la navegación (son enlaces internos, con la almohadilla) y cuando los pulses en la consola aparecerán los valores del hash que se ha alterado.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Almohadilla, gato, numeral con Javascript</title>
  <style>
    p {
      margin-bottom: 100rem;
    }
  </style>
</head>
<body>
  <a name="top"></a>
  
  <h1>Detectar cambios en la URL y enlaces internos</h1>

  <nav>
    <a href="#uno">Uno</a> | 
    <a href="#dos">Dos</a> | 
    <a href="#tres">Tres</a> | 
  </nav>
  <a name="uno"></a>
  <p>
    1. Esta página se hace para detectar cuando un usuario ha hecho clic en un enlace interno.
    <br>
    <a href="#top">Top</a>
  </p>
  <a name="dos"></a>
  <p>
    2. Con Javascript vamos a detectar cuándo el navegador ha navegado a un enlace interno
    <br>
    <a href="#top">Top</a>
  </p>
  <a name="tres"></a>
  <p>
    3. Luego detectaremos el contenido del enlace interno
    <br>
    <a href="#top">Top</a>
  </p>

  <script>
    // Manejador de evento, 
    // Se ejecutará cada vez que cambie el fragmento (lo que hay después de la almohadilla o numeral) de la URL
    function onHashChange() {
        var hashValue = window.location.hash;
        console.log("Hash actual:", hashValue);
    }

    // Agregar el manejador para el evento hashchange del objeto window
    window.addEventListener("hashchange", onHashChange);

    // Puede ser útil ejecutar la función también al cargar la página, 
    // Puedes usar el evento "load" o "DOMContentLoaded" del objeto window
    // Así detectaremos el hash por si alguien entra directamente en un enlace profundo
    window.addEventListener("DOMContentLoaded", onHashChange);

  </script>
</body>
</html>

Con lo que hemos visto en este artículo tendrías la base tecnológica de JavaScript que se utiliza en los sistemas de routing, aunque el ejemplo de página anterior no tiene ninguna funcionalidad especial para intercambiar las vistas de la aplicación, que es lo que hacen las SPA para funcionar y dar el aspecto de un sitio completo con varias pantallas dentro de la misma página.

Simplemente pretendía demostrar el mecanismo que puedes utilizar para detectar los cambios en el hash. Si te interesa, ahora podrías hacer una ampliación del ejemplo para cambiar el contenido de la página a tu gusto cuando surgen esos cambios en el fragmento (hash). Para ello generalmente te apoyarás en algunas librerías que te permitan la manipulación del DOM de manera sencilla. Pero eso ya es otro asunto.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual