window.onload vs <body onload = “” />

227

¿Cuál es exactamente la diferencia entre el window.onloadevento y el onloadevento de la bodyetiqueta? ¿Cuándo uso cuál y cómo se debe hacer correctamente?

Manu
fuente
2
debe usar "para rodear el valor del atributo
Sven Larson

Respuestas:

218

window.onload = myOnloadFuncy <body onload="myOnloadFunc();">son diferentes formas de usar el mismo evento . Utilizandowindow.onload embargo, el es menos molesto: elimina su JavaScript del HTML.

Todas las bibliotecas comunes de JavaScript, Prototype, ExtJS, Dojo, JQuery, YUI, etc. proporcionan buenos envoltorios alrededor de los eventos que ocurren cuando se carga el documento. Puede escuchar la ventana del evento onLoad y reaccionar a eso, pero onLoad no se activa hasta que se hayan descargado todos los recursos, por lo que su controlador de eventos no se ejecutará hasta que se haya recuperado la última gran imagen. En algunos casos, eso es exactamente lo que desea, en otros puede encontrar que escuchar cuando el DOM está listo es más apropiado: este evento es similar a onLoad pero se dispara sin esperar a que se descarguen las imágenes, etc.

Richard Turner
fuente
57
Cabe señalar, sin embargo, que hay una diferencia. El evento de carga en línea va a llamar myOnloadFunc()en el contexto global ( thisse referirá a window). Al configurarlo a través de JavaScript, se ejecutará en el contexto del elemento (se thisrefiere al elemento en el que se activó el evento). En este caso particular, no hará la diferencia, pero sí con otros elementos.
mowwwalker
1
@ Walkerneo: Sí, definitivamente vale la pena señalar. Por supuesto, usando una biblioteca JS, uno puede anular el objeto al que se thisrefiere si lo desea.
Richard Turner
@RichardTurner No necesita usar una biblioteca para cambiar el enlace de contexto. Una simple llamada .bind () hace eso
Kloar
@Kloar puedes en estos días, sí, pero necesitas MSIE9 +. En el MSIE anterior, que era mucho más común cuando respondía, necesitarías un polyfill.
Richard Turner
33

No hay diferencia, pero tampoco debes usarlo.

En muchos navegadores, el window.onloadevento no se activa hasta que se hayan cargado todas las imágenes, que no es lo que desea. Los navegadores basados ​​en estándares tienen un evento llamado DOMContentLoadedque se activa antes, pero IE no lo admite (al momento de escribir esta respuesta). Recomiendo usar una biblioteca de JavaScript que admita una función DOMContentLoaded de navegador cruzado, o encontrar una función bien escrita que pueda usar. jQuery's $(document).ready(), es un buen ejemplo.

jcampbell1
fuente
53
Pregunta del futuro ... ¿Qué pasa si no hay jquery?
Sid
54
Pregunta del presente ... ¿Qué pasa si jQuery es excesivo para el proyecto en cuestión? (No toques jQuery, úsalo yo mismo. Solo a veces solo quiero una característica de una biblioteca ...)
Bradmage
14
Cuando dices "no compatible con IE", ¿es eso una verdad universal, o solo verdadera para versiones específicas de IE? Dado que muchas cosas han cambiado en el mundo del navegador desde que escribió esta respuesta, ¿tal vez es hora de actualizar esta respuesta?
Bryan Oakley
8
DOMContentLoaded ahora es compatible con IE9 y versiones posteriores: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam
66
Informes desde el futuro, DOMContentLoaded ahora es compatible con todos los principales navegadores: caniuse.com/#feat=domcontentloaded
Jose Gómez
21

window.onloadPuede trabajar sin cuerpo. Cree una página con solo las etiquetas de script y ábrala en un navegador. La página no contiene ningún cuerpo, pero aún funciona.

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>
John Joseph
fuente
66
El HTML sin la etiqueta del cuerpo no es válido si realmente agrega contenido (que debería estar en una etiqueta del cuerpo). Además, a su etiqueta de script le falta un tipo. ¡Nunca confíe en los navegadores que arreglan su código que no cumple con los estándares! (. Como los navegadores pueden hacerlo de manera diferente o no del todo en el pasado o en el futuro)
Kissaki
44
@Kissaki: ¡HTML estándar no necesita una etiqueta de cuerpo en absoluto!
Robert Siemer
55
xhtml1 especifica <!ELEMENT html (head, body)>[1] - y html401 también especifica <!ELEMENT HTML O O (%html.content;)con <!ENTITY % html.content "HEAD, BODY">[2]. html51 indica también el A head element followed by a body element.contenido html. [3] w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/html51/semantics.html#the -html-elemento - Así que supongo que todas esas normas comunes de HTML / en uso hacerlo requeriría un cuerpo de la etiqueta. :)
Kissaki
1
@Kissaki es XHTML, no HTML. HTML permite la omisión de etiquetas de las etiquetas del cuerpo inicial y final, así como la omisión de las etiquetas html y head, según su DTD de SGML. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded el
1
@Kissaki: html5 ya no necesita el tipo de script (si es javascript), tienes razón para versiones anteriores.
Mark
10

Prefiero, en general, no usar el <body onload=""evento>. Creo que es más limpio mantener el comportamiento separado del contenido tanto como sea posible.

Dicho esto, hay ocasiones (generalmente bastante raras para mí) en las que usar la carga corporal puede aumentar ligeramente la velocidad.

Me gusta usar Prototype, así que generalmente pongo algo como esto en el <head> de mi página:

document.observe("dom:loaded", function(){
  alert('The DOM is loaded!');
});

o

Event.observe(window, 'load', function(){
  alert('Window onload');
});

Los anteriores son trucos que aprendí aquí . Soy muy aficionado al concepto de controladores de eventos adjuntos fuera del HTML.

(Editar para corregir el error de ortografía en el código).

Mark Biek
fuente
¿En qué ocasiones sería más rápido y por qué?
Kissaki
Esta respuesta parece muy subjetiva con todas las "I" ("Prefiero", "Creo"). Eso si aún carece de hechos objetivos y verificables más o menos apoya esa impresión.
Kissaki
1
Tomaría esta respuesta con un grano de sal considerando que fue publicada hace más de 6 años. Le invitamos a actualizarlo o publicar su propia respuesta mejorada.
Mark Biek
7

'tantas respuestas subjetivas a una pregunta objetiva. JavaScript "discreto" es una superstición como la antigua regla de nunca usar gotos. Escriba el código de una manera que lo ayude a lograr su objetivo de manera confiable, no de acuerdo con las creencias religiosas modernas de alguien.

Cualquiera que encuentre:

 <body onload="body_onload();">

ser demasiado molesto es demasiado pretencioso y no tiene sus prioridades claras.

Normalmente pongo mi código JavaScript en un archivo .js separado, pero no encuentro nada engorroso enganchar controladores de eventos en HTML, que por cierto es HTML válido.


fuente
39
Hay una buena razón para escribir JavaScript discreto. Supongamos que tiene una aplicación web con 100 páginas y utilizó el método <body onload = "body_onload ();"> en lugar de incluirlo en el archivo javascript incluido en cada página. Luego imagine que necesita cambiar el nombre de esa función por alguna razón. Poner el evento en el archivo javascript incluido 1) hace los cambios mucho más simples y 2) ahorra recursos del servidor ya que los archivos javascript pueden almacenarse en caché durante un año (en un servidor configurado correctamente) en lugar de descargar el mismo código una y otra vez.
Andrew Ensley
21
Entonces, porque no te molestas en aprender por qué se recomienda algo, ¿etiquetas las recomendaciones como "creencias religiosas de moda"?
Sabores
66
La pregunta es "¿cuál es la diferencia entre estos dos métodos?", Junto con una solicitud de recomendación para cuál es mejor. ¿Cómo responde tu respuesta a esa pregunta?
Richard Turner
1
Cualquier situación en la que realice una solución modular en 1 lugar que pueda aplicarse a una gran masa de archivos es mucho mejor que agregar el código a cada una de las masas de archivos en sí. Es mejor para el tiempo de compilación original, para propósitos de organización del código, para facilitar la lectura y para futuras ediciones. No está de moda, en realidad es un concepto más antiguo que está presente en lenguajes como Java y C ++ que los programadores web ahora están adoptando como la mejor manera de codificar.
Jimbo Jonny el
1
Una buena defensa contra los ataques XSS en los navegadores modernos es desactivar todos los javascript en línea con su Política de seguridad de contenido. Esa es una buena razón para no usar el atributo onload en tu HTML.
Greg Ball
4

window.onload- Llamado después de todos los archivos DOM, JS, imágenes, marcos flotantes, extensiones y otros completamente cargados. Esto es igual a $ (ventana) .load (function () {});

body onload=""- Llamado una vez que DOM cargado. Esto es igual a $ (documento) .ready (function () {});

Yesu Raj
fuente
1
¿Alguien puede obtener esto? He visto esta declaración en muchos foros, pero nunca con un enlace a donde se define en la especificación.
Crempp
1
@crempp Hay El elemento del cuerpo y los atributos globales , por lo que diría que esto no es cierto. Pero puede probar esto usted mismo, consulte jsbin.com/OmiViPAJ/1/edit . Allí, puede ver que el evento de carga de la imagen se dispara antes del evento de carga del cuerpo.
Olaf Dietsche
2
Esta respuesta contradice a otros; puedes proporcionar una fuente?
Jimmy Breck-McKye
2
api.jquery.com/ready Los documentos de jQuery dicen: "El método .ready () es generalmente incompatible con el atributo <body onload =" ">". Creo que en jQuery está más cerca de body.onload $ (window) .load (..) pero creo que todavía son diferentes.
ccsakuweb
2
Esta respuesta es completamente incorrecta y no debería tener ningún voto positivo. De hecho, este tipo de respuesta generalmente se cita como uno de los mayores conceptos erróneos sobre los eventos readyvs. se activa después de cargar todo el documento, incluidos todos los scripts, imágenes y hojas de estilo. se dispara después de que se haya construido el árbol DOM pero antes de las imágenes, etc. Esto tiene equivalencia con , no . onloadloadDOMContentLoadedDOMContentLoadeddocument.readyload
rism
2

No hay diferencia ...

Así que, en principio, podrías usar ambos (¡uno a la vez! -)

Pero en aras de la legibilidad y la limpieza del código html, siempre prefiero la ventana.onload! O]

Roenving
fuente
1

Si está intentando escribir código JS discreto (y debería serlo), entonces no debería usarlo <body onload="">.

Tengo entendido que diferentes navegadores manejan estos dos de manera ligeramente diferente, pero funcionan de manera similar. En la mayoría de los navegadores, si define ambos, se ignorará uno.

Dr. Bob
fuente
1

Piense en la carga como cualquier otro atributo. En un cuadro de entrada, por ejemplo, podría poner:

<input id="test1" value="something"/>

O puedes llamar:

document.getElementById('test1').value = "somethingelse";

El atributo onload funciona de la misma manera, excepto que toma una función como su valor en lugar de una cadena como lo hace el atributo de valor. Eso también explica por qué puede "usar solo uno de ellos": al llamar a window.onload reasigna el valor del atributo onload para la etiqueta body.

Además, como dicen otros aquí, generalmente es más limpio mantener el estilo y javascript separados del contenido de la página, razón por la cual la mayoría de las personas recomiendan usar window.onload o como la función lista de jQuery.

Soldarnal
fuente
1

<body onload = ""> debería anular window.onload.

Con <body onload = "">, document.body.onload puede ser nulo, indefinido o una función que depende del navegador (aunque getAttribute ("onload") debería ser algo consistente para obtener el cuerpo de la función anónima como una cadena) . Con window.onload, cuando le asigna una función, window.onload será una función consistente en todos los navegadores. Si eso te importa, usa window.onload.

window.onload es mejor para separar el JS de su contenido de todos modos. No hay muchas razones para usar <body onload = ""> de todos modos cuando puedes usar window.onload.

En Opera, el destino del evento para window.onload y <body onload = ""> (e incluso window.addEventListener ("load", func, false)) será la ventana en lugar del documento como en Safari y Firefox. Pero, 'esto' será la ventana a través de los navegadores.

Lo que esto significa es que, cuando es importante, debe envolver la basura y hacer que las cosas sean consistentes o usar una biblioteca que lo haga por usted.

Sombra2531
fuente
0

Ambos trabajan igual. Sin embargo, tenga en cuenta que si ambos están definidos, solo se invocará uno de ellos. Generalmente evito usar cualquiera de ellos directamente. En su lugar, puede adjuntar un controlador de eventos al evento de carga. De esta manera, puede incorporar más fácilmente otros paquetes JS que también podrían necesitar adjuntar una devolución de llamada al evento de carga.

Cualquier marco JS tendrá métodos de navegador cruzado para controladores de eventos.

KernelM
fuente
0

Es un estándar aceptado tener contenido, diseño y comportamiento separados. Entonces window.onload () será más adecuado para usar que <body onload="">aunque ambos hagan el mismo trabajo.

Rajeshwaran SP
fuente
0

Perdón por la reencarnación de este hilo nuevamente después de otros 3 años de sueño, pero quizás finalmente encontré el beneficio indiscutible de window.onload=fn1;terminar <body onload="fn1()">. Se trata de los módulos JS o módulos ES : cuando su onloadcontrolador reside en el archivo JS "clásico" (es decir, se refiere sin <script type="module" … >, de cualquier manera es posible; cuando su onloadcontrolador reside en el archivo JS "módulo" (es decir, se refiere <script type="module" … >, <body onload="fn1()">fallará con "fn1) () no está definido "error. La razón quizás es que los módulos ES no se cargan antes de analizar HTML ... pero es solo mi suposición. De todos modos, window.onload=fn1;funciona perfectamente con módulos ...

Petr Pivonka
fuente