JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Detectar que la página actual está lista

Esto a simple vista es una tarea sencilla, ya que de toda la vida las páginas HTML disponen de un evento onload que nos permite detectar cuando el documento ha cargado por completo.

Por ejemplo, si escribimos:

   1: <body onload="doWhatYouNeed();">
   2: ......
   3: </body>

spongebob_readyEn cuanto el documento esté completamente cargado se llamará de manera automática a la función doWhatYouNeed.

Nota: A partir de ahora haré todos los ejemplos prácticos en inglés para facilitar su localización posterior a este idioma, así que no te extrañes de ver los nombres de las variables, métodos... e incluso la interfaz de usuario en el idioma de Shakespeare.

Esto nos asegura que cuando se llame a la función todos los elementos de la página estarán cargados y listos para su uso, incluyendo los que hay que cargar en una segunda fase tras la carga del HTML de la página: imágenes, CSS, etc...

Sin embargo en muchas ocasiones nos hará falta detectar una fase anterior en el ciclo de vida de la página: cuando la jerarquía de objetos está lista para ser utilizada. Esto implica que se ha interpretado todo el HTML, se han cargado los scripts y por lo tanto se puede manipular el contenido del documento sin problemas. En este momento puede que todavía no se hayan cargado las imágenes y otros elementos, pero podemos manipular sin problemas el DOM ya que éste ha sido generado por completo.

jQuery nos ofrece el método ready()para detectar esta circunstancia, facilitándonos mucho la vida, pues basta con definir una función dentro de éste para que sea llamada en cuanto la página esté lista para ser manipulada.

En este post explicaré como conseguir esta misma funcionalidad directamente con JavaScript y para todos los navegadores del mercado, sin utilizar ninguna biblioteca externa.

La propiedad readyState

Esta propiedad readyState, del objeto document, disponible en todos los navegadores actuales (en Firefox desde la versión 3.6), nos devuelve una cadena de texto que indica el estado actual de la página. Los valores que puede tener son los siguientes, ordenados por el momento en el que se producen dentro del ciclo de vida de la página:

uninitialized No se ha inicializado aún
loading Se están empezando a cargar los datos de la página, e interpretando el HTML
loaded Se han cargado ya los elementos en la jerarquía de la página
interactive El usuario ya puede interactuar con los elementos de la página aunque todavía no estén cargados todos (por ejemplo, faltan las imágenes).
complete Se ha terminado de cargar la página completamente

De acuerdo. Entonces a partir de esta propiedad es sencillo determinar en qué estado se encuentra nuestra página, y si está en estado loaded o superior entonces sabemos que podemos ya interactuar con el DOM desde nuestros scripts.

Pero ¿cómo detectamos el cambio de estado?

Detectar el cambio de estado

Internet Explorer y Ópera ofrecen un evento para la página muy útil llamado onreadystatechange. Es posible interceptarlo y cada vez que cambie el estado se nos notificará de ello, pudiendo actuar en consecuencia. El problema que tiene su uso es que no es multiplataforma, ya que no funcionará en Firefox, ni Chrome ni Safari, ni en los navegadores móviles.

Entonces ¿cómo podemos hacer para solventar este problema?

Vamos a tomar otro camino y lo que haremos será comprobar en intervalos muy cortos el estado actual de la página usando un temporizador de JavaScript.

El código es muy sencillo:

   1: var tmrReady = setInterval(isPageFullyLoaded, 100);
   2:  
   3: function isPageFullyLoaded() {
   4:     if (document.readyState == "loaded" || document.readyState == "interactive" || document.readyState == "complete") {
   5:         doWhatYouWant();
   6:         clearInterval(tmrReady);
   7:     }
   8: }

Como vemos lo que se hace es crear un temporizador periódico, que cada 100 milisegundos llame a la función isPageFullyLoaded. En ésta lo que se hace es comprobar si el documento se encuentra actualmente en alguna de las fases en las que ya es posible manipular el DOM, en cuyo caso llamamos a la función que nos interese, para hacer lo que sea, y además (y esto es muy importante), eliminamos el temporizador pues ya no nos va a resultar útil.

Podríamos usar un intervalo menor (por ejemplo de 50 milisegundos) pero normalmente con 100 es más que suficiente y no así cargamos menos la ejecución inicial de la página.

Con este truco podremos detectar el estado de la página de forma muy sencilla y conseguir lo mismo que el ready de jQuery sin necesidad de cargar toda la biblioteca jQuery para algo tan pequeño.

¡Espero que te resulte útil!

Para saber más: JavaScript profesional para desarrolladores y diseñadores web

José Manuel Alarcón José Manuel Alarcón
Fundador de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (3) -

Spain Hector Hernandez

Hola buenas,

  Se puede aplicar esto en vba o vbs??? Tengo un proceso en vba/vbs para excel, que lanza el navegador, se espera un rato y rellena un formulario, lo envia, espera a que cargue, y se guarda la pagina resultante como texto.
De momento estoy reciclando un codigo de "Sleep XXX" que saque de otra web, pero esto tiene muy buena pinta.
La pregunta es... como adapto el codigo para que el VB detecte el estado del firefox/iexplore/chrome??

Me valdria tambien sin contar para nada con excel, solo lo uso para coger los valores de la lista.

Muchas gracias por el tuto. Saludos

Responder

Spain José M. Alarcón

Esto no tiene nada que ver con lo que preguntas, así que la respuesta es que no. Lo siento.

Responder

Muchas gracias, me ayudó con jquery datatables a lanzarlo ya que estuviera todo cargado, porque de otra forma entraba antes y no funcionaba correctamente.
Saludos.

Responder

Pingbacks and trackbacks (3)+

Agregar comentario