El Atributo ONHASHCHANGE

Es un evento de JavaScript que se activa cuando cambia el fragmento de la URL, es decir, la parte después del #.

El atributo onhashchange es un evento de JavaScript que se activa cuando cambia el fragmento de la URL (la parte después del #). Es clave para crear aplicaciones de una sola página (SPA), manejar navegación dinámica y sincronizar el estado de la aplicación con la URL sin recargar la página.

¿Qué es el fragmento (hash) de la URL?

  • Formato: https://ejemplo.com/#seccion1

    • #seccion1 es el "hash" o "fragmento".

  • Características:

    • No envía solicitudes al servidor.

    • Permite navegación interna y control de estado en el cliente.

¿Qué hace onhashchange?

  • Disparador: Cuando el hash cambia (manual o programáticamente).

  • Casos de uso:

    • Navegación entre secciones sin recargar.

    • Sincronizar el estado de la aplicación con la URL.

    • Implementar historial de navegación en SPAs.

Sintaxis básica

Como atributo HTML (en <body>):

<body onhashchange="manejarCambioHash()">
  <!-- Contenido -->
</body>

Con JavaScript (recomendado):

window.addEventListener("hashchange", (e) => {
  console.log("Hash cambiado:", window.location.hash);
});

Ejemplos prácticos

Ejemplo 1: Navegación básica entre secciones

<nav>
  <a href="#inicio">Inicio</a>
  <a href="#contacto">Contacto</a>
</nav>
<div id="contenido"></div>

<script>
  window.addEventListener("hashchange", () => {
    const hash = window.location.hash.substring(1); // Elimina el #
    const contenido = {
      inicio: "<h2>Bienvenido</h2>",
      contacto: "<h2>Email: contacto@ejemplo.com</h2>"
    };
    document.getElementById("contenido").innerHTML = contenido[hash] || "Página no encontrada";
  });

  // Cargar contenido inicial
  window.dispatchEvent(new Event("hashchange"));
</script>

Ejemplo 2: Historial de navegación

<button onclick="window.location.hash = 'pagina1'">Página 1</button>
<button onclick="window.location.hash = 'pagina2'">Página 2</button>

<script>
  window.onhashchange = (e) => {
    const hash = window.location.hash;
    console.log("Navegación:", {
      hash,
      hashAnterior: e.oldURL.split("#")[1] || ""
    });
  };
</script>

Ejemplo 3: Integración con la API History

// Cambiar hash programáticamente con historial
document.getElementById("boton").addEventListener("click", () => {
  history.pushState(null, "", "#configuracion");
  window.dispatchEvent(new Event("hashchange"));
});

// Manejar cambios
window.addEventListener("hashchange", () => {
  console.log("Hash actual:", window.location.hash);
});

Propiedades clave del evento

  • window.location.hash: Devuelve el fragmento actual (ej: #seccion1).

  • event.oldURL y event.newURL: URLs antes y después del cambio (no soportado en todos los navegadores).

Mejores prácticas

Validar el hash:

function obtenerHash() {
  return window.location.hash.replace("#", "") || "inicio";
}

Evitar bucles infinitos:

Si modificas el hash dentro de un listener, asegúrate de no crear recursión.

Compatibilidad con navegadores antiguos:

Usa un polyfill para IE8-:

if (!("onhashchange" in window)) {
  // Implementación alternativa con setInterval
}

Combínalo con history.pushState():

Para un control más fino del historial del navegador.

Casos avanzados

Sistema de rutas en SPA:

const rutas = {
  "/": "<h1>Inicio</h1>",
  "/productos": "<h1>Catálogo</h1>",
  "/contacto": "<h1>Contacto</h1>"
};

window.addEventListener("hashchange", () => {
  const ruta = window.location.hash.substring(1) || "/";
  document.getElementById("app").innerHTML = rutas[ruta] ?? "<h1>404</h1>";
});

Scroll a secciones con animación:

<a href="#seccion1">Sección 1</a>
<div id="seccion1" style="margin-top: 1000px;">Contenido</div>

<script>
  window.addEventListener("hashchange", () => {
    const id = window.location.hash.substring(1);
    const elemento = document.getElementById(id);
    if (elemento) {
      elemento.scrollIntoView({ behavior: "smooth" });
    }
  });
</script>

Errores comunes

// MAL: No manejar el hash inicial
// ¡El evento hashchange no se dispara al cargar la página!
window.addEventListener("load", () => {
  // Disparar manualmente
  if (window.location.hash) {
    manejarCambioHash();
  }
});

// CONFUSIÓN: Usar hash para datos sensibles
window.location.hash = "token=123"; // ¡Visible en el historial y servidores!

Compatibilidad

Navegador Soporte
Chrome ✅ v5+
Firefox ✅ v3.6+
Safari ✅ v5+
Edge ✅ v12+
Móviles ✅ iOS 5+, Android 4.4+

Conclusión

El atributo onhashchange es esencial para:

  • Crear SPAs con navegación fluida.
  • Sincronizar el estado de la aplicación con la URL.
  • Manejar historial sin recargas de página.

Recuerda:

  1. Evita almacenar datos sensibles en el hash.
  2. Combínalo con la API History para un control profesional.
  3. Prueba en navegadores antiguos si es necesario.

¡Ahora puedes implementar sistemas de enrutamiento modernos y dinámicos!