window.onload vs document.onload

712

¿Cuál es más ampliamente compatible: window.onloado document.onload?

Chris Ballance
fuente
2
MDN docs explica estos windoweventos: onloady DOMContentLoaded. Ejemplo de uso :, window.addEventListener('DOMContentLoaded', callback). A mediados de 2019, compatible con todos los principales navegadores. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks
¡Incluso para mí, en Firefox 75.0 hoy, window.onloady document.onloadson diferentes entre sí! window.onloadparece tener lugar después y tiene un poco más cargado que document.onload! (¡Algunas cosas están funcionando con la ventana que no funciona con el documento! ¡Eso va para document.onreadstatechange 'complete' también!)
Andrew

Respuestas:

723

¿Cuándo disparan?

window.onload

  • Por defecto, se dispara cuando se carga toda la página, incluido su contenido (imágenes, CSS, scripts, etc.).

En algunos navegadores, ahora asume el papel document.onloady se activa cuando el DOM también está listo.

document.onload

  • Se llama cuando el DOM está listo, que puede ser anterior a las imágenes y se carga otro contenido externo.

¿Qué tan bien son compatibles?

window.onloadparece ser el más ampliamente apoyado. De hecho, algunos de los navegadores más modernos tienen en un sentido reemplazado document.onloadcon window.onload.

Los problemas de soporte del navegador son probablemente la razón por la cual muchas personas están comenzando a usar bibliotecas como jQuery para manejar la verificación del documento que está listo, así:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

A los efectos de la historia. window.onloadvs body.onload:

Hace un tiempo se hizo una pregunta similar en los foros de codificación con respecto al uso de window.onloadover body.onload. El resultado parece ser que debe usar window.onloadporque es bueno separar su estructura de la acción.

Josh Mein
fuente
25
En realidad, esa afirmación parece estar dirigida a una elección entre window.onloady <body onload="">que es completamente diferente (y la "estructura separada de la acción" tiene mucho más sentido en este contexto). No es que la respuesta sea incorrecta, pero la base es.
Thor84no
2
Esa cita es gramaticalmente horrible ... ¿no debería alguna ayuda de edición (marcada)?
Kheldar
@ Thor84no Finalmente encontré el tiempo para mirar eche otro vistazo a esto. He hecho algunas mejoras.
Josh Mein el
@Kheldar Decidí parafrasear la cita ya que era bastante tosca.
Josh Mein el
@JoshMein ¿Significa que document.onloades JS equivalente a jQuery document.ready?
john cj
276

La idea general es que los fuegos window.onload cuando la ventana del documento está listo para su presentación y document.onload incendios cuando el árbol DOM es (construido a partir del código de marcado dentro del documento) completó .

Idealmente, suscribirse a los eventos del árbol DOM permite manipulaciones fuera de la pantalla a través de Javascript, casi sin carga de CPU . Por el contrario, window.onloadpuede tardar un tiempo en activarse , cuando aún no se han solicitado, analizado y cargado múltiples recursos externos.

► Escenario de prueba:

Para observar la diferencia y cómo su navegador de elección implementa los controladores de eventos mencionados anteriormente , simplemente inserte el siguiente código dentro de la <body>etiqueta - - de su documento .

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Resultado:

Aquí está el comportamiento resultante, observable para Chrome v20 (y probablemente la mayoría de los navegadores actuales).

  • No hay document.onloadevento
  • onloadse dispara dos veces cuando se declara dentro de <body>, una vez cuando se declara dentro de <head>(donde el evento actúa como document.onload).
  • contar y actuar en función del estado del contador permite emular ambos comportamientos de eventos.
  • Alternativamente, declare el window.onloadcontrolador de eventos dentro de los límites del <head>elemento HTML .

► Proyecto de ejemplo:

El código anterior se toma de la base de código de este proyecto ( index.htmly keyboarder.js).


Para obtener una lista de controladores de eventos del objeto de ventana , consulte la documentación de MDN.

Lorenz Lo Sauer
fuente
143

Agregar escucha de eventos

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1 JavaScript de vainilla

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


Buena suerte.

Akash
fuente
14
"El evento DOMContentLoaded se activa cuando el documento HTML inicial se ha cargado y analizado por completo, sin esperar a que las hojas de estilo, las imágenes y los subtramas terminen de cargarse". - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Así que parece estar equivocado acerca de todo lo que se carga en este evento.
ProfK
2
@ProfK, gracias por sus comentarios. ¿Puedes intentarlo window.addEventListener('load', function() {...})? También he actualizado mi respuesta.
Akash
44
Lo que me gusta de esta respuesta es que ofrece una solución javascript antigua. Se podría pensar que la mayoría de la gente piensa que jQuery está integrado en todos los navegadores, dada la frecuencia con la que se da como la única respuesta.
Dave Land
Doble problema cuando el maldito jquery tarda demasiado en cargar y obtienes $ no encontrado. Soy de la opinión de que las soluciones de tipo $ (window) .ready NUNCA deberían ser confiables para funcionar.
Shayne
1
He probado ambos en el cromo de hoy. No está esperando css y fuentes.
movAX13h
78

De acuerdo con el análisis de documentos HTML - El final ,

  1. El navegador analiza la fuente HTML y ejecuta scripts diferidos.

  2. A DOMContentLoadedse envía en el documentmomento en que todo el HTML se ha analizado y se ha ejecutado. El evento burbujea a la window.

  3. El navegador carga recursos (como imágenes) que retrasan el evento de carga.

  4. Se loadenvía un evento a las window.

Por lo tanto, el orden de ejecución será

  1. DOMContentLoadedoyentes de eventos windowen la fase de captura
  2. DOMContentLoaded oyentes de eventos de document
  3. DOMContentLoadedoyentes de eventos windowen la fase de burbuja
  4. loadoyentes de eventos (incluido el onloadcontrolador de eventos) dewindow

Nunca se debe invocar un loaddetector de eventos de burbuja (incluido el onloadcontrolador de eventos) document. Solo se loadpueden invocar oyentes de captura , pero debido a la carga de un recurso secundario como una hoja de estilo, no debido a la carga del documento en sí.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};

Oriol
fuente
Ejecuté su fragmento y document - load - capture, de hecho, sucede, lo cual es contrario a lo que esperaba en mi búsqueda de por qué la carga de documentos no me está sucediendo. Curiosamente, es inconsistente. A veces aparece, a veces no, a veces aparece dos veces, pero nunca document - load - bubblesucede. Sugeriría no usar document load.
erróneo
@erroric Buen punto. No consideré que loadse envíe un evento con recursos externos. Ese evento no burbujea, por lo que generalmente no se detecta en el documento, pero debería aparecer en la fase de captura. Estas entradas se refieren a la carga de los elementos <style>y <script>. Creo que Edge tiene razón para mostrarlos, y Firefox y Chrome están equivocados.
Oriol
Gracias Oriol, la useCaptureopción me enseñó algo nuevo.
Paul Watson
Gracias por resumir el flujo de análisis y representación de w3. Me pregunto después del paso 4 una vez que se activa el evento 'cargar', ¿qué más puede suceder? Noté en mi navegador que a veces todavía se obtienen algunos objetos después de que se activa el evento de carga, aunque no he tocado ni interactuado con la página. ¿Sabes cómo se llaman esos objetos? '¿Objetos de representación sin bloqueo?
weefwefwqg3
12

En Chrome, window.onload es diferente de <body onload="">, mientras que son iguales tanto en Firefox (versión 35.0) como en IE (versión 11).

Puede explorar eso con el siguiente fragmento:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

Y verá tanto "ventana cargada" (que viene primero) como "carga del cuerpo" en la consola de Chrome. Sin embargo, verá solo "carga del cuerpo" en Firefox e IE. Si ejecuta " window.onload.toString()" en las consolas de IE y FF, verá:

"función onload (evento) {bodyOnloadHandler ()}"

lo que significa que la asignación "window.onload = function (e) ..." se sobrescribe.

VincentZHANG
fuente
6

window.onloady onunloadson atajos hacia document.body.onloadydocument.body.onunload

document.onloady el onloadcontrolador en todas las etiquetas html parece estar reservado, pero nunca se activó

' onload' en el documento -> verdadero

garaboncias
fuente
5

window.onload, sin embargo, a menudo son lo mismo. Del mismo modo, body.onload se convierte en window.onload en IE.

AnthonyWJones
fuente
1

Sin embargo, Window.onload es el estándar: el navegador web en la PS3 (basado en Netfront) no admite el objeto de la ventana, por lo que no puede usarlo allí.

Gotofritz
fuente
0

En breve

  • windows.onloadno es compatible con IE 6-8
  • document.onload no es compatible con ningún navegador moderno (el evento nunca se activa)

Kamil Kiełczewski
fuente