> Manuales > Manual de Ajax práctico

Ejemplos de Ajax usando objetos XMLHttpRequest en los que implementamos un mensaje de carga para indicar que la solicitud está en curso. Conoceremos también el evento onreadystatechange.

Mensaje de carga en solicitudes Ajax con XMLHttpRequest

Una de las mejoras fundamentales en los comportamientos Ajax es la realización de mensajes de carga, el típico spinner o ruedita que gira, indicando que el proceso de la solicitud se está realizando. En este artículo vamos a mostrar diversos ejemplos de Ajax en los que usamos la interfaz XMLHttpRequest e implementamos un aviso de carga.

Por qué es necesario mostrar un aviso de carga

Los usuarios cuando pulsan enlaces o envían formularios están acostumbrados a que el navegador responda de inmediato, navegando hacia otra página web. Esa página tardará unos segundos en cargar, pero al menos ellos ven que la página se ha refrescado.

Las solicitudes Ajax, en cambio, no refrescan la página, por lo que el típico mensaje "cargando..." avisa a los visitantes que el enlace o formulario está funcionando bien y evita una mala experiencia de usuario. De hecho, si la solicitud tarda en cargar más de 4 o 5 segundos es muy probable que el usuario piense que no está funcionando correctamente, por lo que intentará enviar de nuevo el formulario, pulsará otra vez el enlace o simplemente se irá a otro sitio.

Mostrar un mensaje de carga es muy sencillo y con unas pocas líneas de Javascript lo puedes conseguir, como veremos en este articulo.

Cómo mostrar y ocultar un elemento

Vamos a comenzar explicando cómo mostrar y ocultar un elemento en la página, aunque no tenga que ver específicamente con el tema de Ajax, simplemente para que esta parte no sorprenda a nadie.

Tenemos un elemento en la página como este:

<div id="cargando" style="display: none;">cargando...</div>

Ese es nuestro mensaje de carga. Tiene un texto, pero podría perfectamente tener el típico gif animado que muestra una ruedita girando. Fíjate que el elemento está oculto inicialmente, gracias al atributo style="display: none;".

Ahora vamos a hacer una función que se encarga de mostrar y ocultar ese elemento.

// Una función que cambia la visibilidad del mensaje de carga
function cambiarVisibilidad(esVisible) {
  // accedemos al objeto del elemento "cargado"
  const cargando = document.getElementById('cargando');
  if(esVisible) {
    cargando.style.display = 'block';
  } else {
    cargando.style.display = 'none';
  }
}

Simplemente recibimos un boleano, que nos dirá si el elemento debe ser visible o no. Luego, dependiendo de ese boleano hacemos un cambio en el style del elemento. No tiene mucho misterio.

Cómo aplicar el mensaje de carga al inicio de la solicitud Ajax

En nuestro primer ejemplo de Ajax vamos a implementar el mensaje de carga con lo que hemos aprendido ya en el Manual de Ajax, concretamente en el artículo de Ajax con XMLHttpRequest. Luego veremos otras alternativas en las que aprenderemos nuevas cosas de XMLHttpRequest que nos permitirán hacer el mismo trabajo de una manera distinta.

Básicamente, lo que vamos a hacer es que, antes de iniciar la solicitud Ajax, invocaremos a la función que muestra/oculta el elemento de carga. Luego, cuando recibamos la respuesta, invocaremos a la función para que oculte el mensaje.

Voy a tener un enlace en la página, que tiene este aspecto:

<a href="cuenta-clics.php" id="cuentaclics">Cuenta clics</a>

Este enlace llama a una página PHP que simplemente hace una cuenta del número de clics que se han realizado sobre el enlace, desde el servidor. El servidor simplemente nos devolverá un número que se irá incrementando en cada solicitud.

Ese trabajo en PHP lo realizaremos por medio de variables de sesión. Luego veremos el código, ya que ahora importa poco.

Si dejamos el enlace tal cual, se invocaría la página PHP de manera común, refrescando el navegador. Por ello, ahora vamos a ver el código que implementa la solicitud Ajax cuando se haga clic sobre el enlace.

// accedemos al enlace y definimos un manejador de evento
const link = document.getElementById('cuentaclics');
link.addEventListener('click', function(e) {
  // evitamos el comportamiento predeterminado del enlace
  e.preventDefault();
  // Hacemos que el mensaje de carga se muestre
  cambiarVisibilidad(true);
  // Configuramos la solicitud Ajax
  let xhr = new XMLHttpRequest();
  xhr.open("GET", link.href);
  xhr.onload = function (e) {
    link.innerText = "Has hecho " + xhr.responseText + " clicks";
    cambiarVisibilidad(false);
  }
  // Realizamos la solicitud
  xhr.send();
});

El código está comentado para que se pueda entender correctamente. Ten en cuenta que en artículos anteriores del Manual de Ajax ya explicamos cómo funciona XMLHttpRequest. Lo que nos interesa ahora a nosotros es lo siguiente:

Evento onreadystatechange de XMLHttpRequest

Ahora vamos a aprender a hacer la misma operación pero usando nuevas alternativas de trabajo con XMLHttpRequest. Para ello vamos a conocer el evento onreadystatechange que permite definir un comportamiento cada vez que cambia el estado de la solicitud Ajax.

Este evento se define igualmente sobre el objeto de la clase XMLHttpRequest, igual que hemos visto con onload.

xhr.onreadystatechange = function(evento) {
  console.log('estado de la solicitud', xhr.readyState);
}

La función recibe un objeto evento, desde el que podemos obtener algunas informaciones. Sin embargo, lo que realmente nos interesa para conocer el estado de la solicitud es la propiedad readyState del objeto XMLHttpRequest.

Cambios en esta propiedad son los que desencadenan el evento onreadystatechange que estamos usando, por lo que cada vez que se ejecute este evento tendremos un valor distinto en readyState.

Los valores que podremos encontrar en esta propiedad son enteros cuyos significados son los siguientes:

Ahora vamos a ver el código de nuestro comportamiento Ajax completo, en el que estamos usando el evento onreadystatechange.

// accedemos al enlace y definimos un manejador de evento
const link = document.getElementById('cuentaclics');
link.addEventListener('click', function(e) {
  // evitamos el comportamiento predeterminado del enlace
  e.preventDefault();
  // Hacemos que el mensaje de carga se muestre
  cambiarVisibilidad(true);
  // Configuramos la solicitud Ajax
  let xhr = new XMLHttpRequest();
  xhr.open("GET", link.href);
  // evento de carga completa
  xhr.onload = function (e) {
    link.innerText = "Has hecho " + xhr.responseText + " clicks";
  }
  // evento para distintos estados durante la ejecución de la solicitud
  xhr.onreadystatechange = function(evento) {
    console.log('estado de la solicitud', xhr.readyState);
    if(xhr.readyState == 4) {
      cambiarVisibilidad(false);
    }
  }
  // Realizamos la solicitud
  xhr.send();
});

Realmente solamente queremos quitar el mensaje de carga cuando la solicitud se ha dado por terminada, es decir, cuando readyState vale 4. Por eso solamente hacemos la invocación a cambiarVisibilidad() cuando xhr.readyState == 4.

Este evento onreadystatechange puede resultar de más utilidad en ejemplos donde la respuesta sea muy larga y el servidor lleve un tiempo en entregar todos los datos. Gracias a los distintos estados podremos saber cuándo ha comenzado la devolución de la respuesta y cuándo se está recibiendo ya texto, aunque no se haya completado todavía. En nuestro ejemplo, como la solicitud es muy pequeña, todos los cambios de readyState nos van a llegar de golpe.

Código PHP que cuenta el número de clics

Solo a modo de extra, aunque no tenga mucho (o más bien nada) que ver con la solicitud Ajax, vamos a dejar aquí el código PHP de cuenta-clics.php, donde hacemos uso de una variable de sesión para contar las veces que se ha pulsado sobre el enlace.

<?php
session_start();
sleep(2);
if(isset($_SESSION["clics"])) {
  $_SESSION["clics"]++;
} else {
  $_SESSION["clics"] = 1;
}
echo $_SESSION["clics"];

Recuerda que en el Manual de PHP podrás aprender a trabajar con variables de sesión y muchas otras cosas.

Miguel Angel Alvarez

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

Manual