El ciclo de vida de una página HTML tiene tres eventos importantes:
-
DOMContentLoaded
: el HTML del navegador está completamente cargado y el árbol DOM está construido, pero es posible que los recursos externos como imágenes<img>
y hojas de estilo aún no se hayan cargado. -
load
– no solo se carga HTML, sino también todos los recursos externos: imágenes, estilos, etc. -
beforeunload/unload
– el el usuario está abandonando la página.
Cada evento puede ser útil:
-
DOMContentLoaded
evento – DOM está listo , para que el controlador pueda buscar nodos DOM, inicializar la interfaz. -
load
evento: se cargan recursos externos, por lo que se aplican estilos, se conocen tamaños de imagen, etc. -
beforeunload
evento – el usuario se va: podemos verificar si el usuario guardó los cambios y preguntarle si realmente quiere irse. - : el usuario casi se fue, pero aún podemos iniciar algunas operaciones, como enviar estadísticas.
Exploremos los detalles de estos eventos.
DOMContentLoaded
El evento DOMContentLoaded
ocurre en el objeto document
.
Nosotros debe usar addEventListener
para atraparlo:
Por ejemplo:
En el ejemplo, el controlador DOMContentLoaded
se ejecuta cuando se carga el documento, por lo que puede ver todos los elementos, incluido <img>
a continuación.
Pero no espera a que se cargue la imagen. Entonces alert
muestra tamaños cero.
A primera vista, el evento DOMContentLoaded
es muy simple. El árbol DOM está listo, aquí está el evento. Sin embargo, hay algunas peculiaridades.
DOMContentLoaded y scripts
Cuando el navegador procesa un documento HTML y encuentra una etiqueta <script>
, debe ejecutarse antes de continuar construyendo el DOM. Esa es una precaución, ya que los scripts pueden querer modificar DOM, e incluso document.write
en él, por lo que DOMContentLoaded
tiene que esperar.
Entonces DOMContentLoaded definitivamente ocurre después de tales scripts:
En el ejemplo anterior, primero vemos «Biblioteca cargada …» y luego «¡DOM listo!» (todos los scripts se ejecutan).
Hay dos excepciones a esta regla:
- Scripts con el atributo
async
, que cubriremos un poco más adelante, no bloqueeDOMContentLoaded
. - Los scripts que se generan dinámicamente con
document.createElement("script")
y luego se agregan a la página web tampoco bloquean este evento.
DOMContentLoaded y estilos
Las hojas de estilo externas no afectan a DOM, por lo que DOMContentLoaded
no las espera.
Pero hay una trampa. Si tenemos un script después del estilo, entonces ese script debe esperar hasta que se cargue la hoja de estilo:
La razón de esto es que el script puede querer obtener coordenadas y otras propiedades de elementos dependientes del estilo, como en el ejemplo anterior. Naturalmente, tiene que esperar a que se carguen los estilos.
Mientras DOMContentLoaded
espera los scripts, ahora también espera los estilos antes que ellos.
Autocompletar del navegador integrado
Formularios de autocompletar de Firefox, Chrome y Opera en DOMContentLoaded
.
Por ejemplo, si la página tiene un formulario con nombre de usuario y contraseña, y el navegador recordó los valores, luego en DOMContentLoaded
puede intentar completarlos automáticamente (si el usuario lo aprueba).
Entonces, si DOMContentLoaded
se pospone mediante secuencias de comandos de carga prolongada, luego el autocompletado también espera. Probablemente haya visto eso en algunos sitios (si usa la función de autocompletar del navegador): los campos de inicio de sesión / contraseña no se completan automáticamente de inmediato, pero hay una demora hasta que la página se carga por completo. Ese es en realidad el retraso hasta el evento DOMContentLoaded
.
window.onload
El load
El evento en el objeto window
se activa cuando se carga toda la página, incluidos estilos, imágenes y otros recursos. Este evento está disponible a través de la propiedad onload
.
El siguiente ejemplo muestra correctamente los tamaños de las imágenes, porque window.onload
espera todas las imágenes:
window.onunload
Cuando un visitante abandona la página, el evento unload
se activa en window
. Podemos hacer algo allí que no implique una demora, como cerrar ventanas emergentes relacionadas.
La excepción notable es el envío de análisis.
Digamos que recopilamos datos sobre cómo está la página utilizado: clics del mouse, desplazamientos, áreas de página visitadas, etc.
Naturalmente, el evento unload
es cuando el usuario nos deja y nos gustaría guarda los datos en nuestro servidor.
Envía los datos en segundo plano.La transición a otra página no se retrasa: el navegador abandona la página, pero sigue funcionando sendBeacon
.
A continuación, le indicamos cómo utilizarlo:
- La solicitud se envía como POST.
- Podemos enviar no solo una cadena, sino también formularios y otros formatos, como se describe en el capítulo Obtener, pero generalmente es un objeto en cadena.
- Los datos están limitados por 64 kb.
Cuando la solicitud sendBeacon
finaliza, es probable que el navegador ya haya abandonado el documento, por lo que no hay forma de obtener una respuesta del servidor (que normalmente está vacía para los análisis).
También hay un indicador keepalive
para realizar esas solicitudes «after-page-left» en el método de recuperación para solicitudes de red genéricas. Puede encontrar más información en el capítulo Obtener API.
Si queremos cancelar la transición a otra página, no podemos hacerlo aquí. Pero podemos usar otra event – onbeforeunload
.
window.onbeforeunload
Si un visitante inició la navegación aw ay desde la página o intenta cerrar la ventana, el controlador beforeunload
solicita una confirmación adicional.
Si cancelamos el evento, el navegador puede preguntar al visitante si están seguros.
Puede probarlo ejecutando este código y luego recargando la página:
Por razones históricas, devolver una cadena no vacía también cuenta como cancelación el evento. Hace algún tiempo, los navegadores solían mostrarlo como un mensaje, pero como dice la especificación moderna, no deberían hacerlo.
Aquí hay un ejemplo:
Se cambió el comportamiento , porque algunos webmasters abusaron de este controlador de eventos mostrando mensajes engañosos y molestos. Por lo tanto, en este momento los navegadores antiguos aún pueden mostrarlo como un mensaje, pero aparte de eso, no hay forma de personalizar el mensaje que se muestra al usuario.
readyState
¿Qué sucede si configuramos el controlador DOMContentLoaded
después de cargar el documento?
Naturalmente, nunca se ejecuta.
Hay casos en los que no estamos seguros de si el documento está listo o no. Nos gustaría que nuestra función se ejecute cuando se cargue el DOM, ya sea ahora o más tarde.
La propiedad document.readyState
nos informa sobre el estado de carga actual.
Hay 3 valores posibles:
-
"loading"
: el documento se está cargando. -
"interactive"
: el documento se leyó por completo. -
"complete"
: el documento se leyó completamente y todos los recursos (como imágenes) están cargados también.
Entonces podemos verificar document.readyState
y configurar un controlador o ejecutar el código inmediatamente si está listo.
Hay también el evento readystatechange
que se activa cuando cambia el estado, por lo que podemos imprimir todos estos estados así:
El readystatechange
event es una mecánica alternativa de seguimiento del estado de carga del documento, apareció hace mucho tiempo. Hoy en día, rara vez se usa.
Veamos el flujo de eventos completo para ver si están completos.
Aquí hay un documento con <iframe>
, <img>
y controladores que registran eventos:
El ejemplo de trabajo está en la caja de arena.
El resultado típico:
El los números entre corchetes denotan el tiempo aproximado en que ocurre. Los eventos etiquetados con el mismo dígito ocurren aproximadamente al mismo tiempo (± unos pocos ms).
-
document.readyState
se convierte eninteractive
justo antes deDOMContentLoaded
. Estas dos cosas realmente significan lo mismo. -
document.readyState
se convierte encomplete
cuando todos los recursos (iframe
yimg
) están cargados. Aquí podemos ver que ocurre aproximadamente al mismo tiempo queimg.onload
(img
es el último recurso) ywindow.onload
. Cambiar al estadocomplete
significa lo mismo quewindow.onload
. La diferencia es quewindow.onload
siempre funciona después de todos los demásload
controladores.
Resumen
Eventos de carga de página:
- El evento
DOMContentLoaded
se activa endocument
cuando el DOM está Listo. Podemos aplicar JavaScript a los elementos en esta etapa.- Secuencia de comandos como
<script>https://javascript.info/...</script>
o<script src="https://javascript.info/..."></script>
bloquear DOMContentLoaded, el navegador espera para que se ejecuten. - Las imágenes y otros recursos también pueden continuar cargándose.
- Secuencia de comandos como
- El
load
El evento enwindow
se activa cuando se cargan la página y todos los recursos. Rara vez lo usamos, porque generalmente no hay necesidad de esperar tanto. - El evento
beforeunload
enwindow
se activa cuando el usuario quiere salir de la página. Si cancelamos el evento, el navegador pregunta si el usuario realmente quiere irse (por ejemplo, tenemos cambios sin guardar). - El evento
unload
enwindow
se dispara cuando el usuario finalmente se está yendo, en el manejador solo podemos hacer cosas simples que no involucran demoras o preguntar a un usuario. Debido a esa limitación, rara vez se usa. Podemos enviar una solicitud de red connavigator.sendBeacon
. -
document.readyState
es el estado actual del documento, los cambios pueden ser rastreado en el eventoreadystatechange
:-
loading
– el documento se está cargando. -
interactive
: el documento se analiza, ocurre aproximadamente al mismo tiempo queDOMContentLoaded
, pero antes. -
complete
: el documento y los recursos se cargan, sucede aproximadamente al mismo tiempo quewindow.onload
, pero antes.
-