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


227

Quelle est exactement la différence entre l' window.onloadévénement et l' onloadévénement du bodytag? quand dois-je utiliser lequel et comment le faire correctement?


2
vous devez utiliser "pour entourer la valeur de l'attribut
Sven Larson

Réponses:


218

window.onload = myOnloadFuncet <body onload="myOnloadFunc();">sont différentes façons d'utiliser le même événement . L'utilisation window.onloadest cependant moins intrusive - elle supprime votre JavaScript du HTML.

Toutes les bibliothèques JavaScript courantes, Prototype, ExtJS, Dojo, JQuery, YUI, etc. fournissent de jolis wrappers autour des événements qui se produisent lors du chargement du document. Vous pouvez écouter l'événement onLoad de la fenêtre et y réagir, mais onLoad n'est pas déclenché tant que toutes les ressources n'ont pas été téléchargées. Dans certains cas, c'est exactement ce que vous voulez, dans d'autres, vous pourriez trouver que l'écoute lorsque le DOM est prêt est plus appropriée - cet événement est similaire à onLoad mais se déclenche sans attendre le téléchargement des images, etc.


57
Il convient toutefois de noter qu'il existe une différence. L'événement onload en ligne va appeler myOnloadFunc()dans le contexte global ( thisse référera à window). Le paramétrer via javascript le fera s'exécuter dans le contexte de l'élément ( thisfait référence à l'élément sur lequel l'événement a été déclenché). Dans ce cas particulier, cela ne fera aucune différence, mais ce sera le cas avec d'autres éléments.
mowwwalker

1
@Walkerneo: Oui, ça vaut vraiment la peine d'être noté. Bien sûr, en utilisant une bibliothèque JS, vous pouvez remplacer l'objet auquel thisvous vous référez si vous le souhaitez.
Richard Turner

@RichardTurner Vous n'avez pas besoin d'utiliser une bibliothèque pour modifier la liaison de contexte. Un simple appel .bind () fait cela
Kloar

@Kloar vous pouvez ces jours-ci, oui, mais vous avez besoin de MSIE9 +. Sur les anciens MSIE, qui étaient beaucoup plus courants lorsque j'ai répondu, vous auriez besoin d'un polyfill.
Richard Turner

33

Il n'y a pas de différence, mais vous ne devez pas non plus l'utiliser.

Dans de nombreux navigateurs, l' window.onloadévénement n'est déclenché qu'une fois toutes les images chargées, ce qui n'est pas ce que vous souhaitez. Les navigateurs basés sur des normes ont un événement appelé DOMContentLoadedqui se déclenche plus tôt, mais il n'est pas pris en charge par IE (au moment d'écrire cette réponse). Je recommanderais d'utiliser une bibliothèque javascript qui prend en charge une fonctionnalité DOMContentLoaded multi-navigateur, ou de trouver une fonction bien écrite que vous pouvez utiliser. jQuery $(document).ready(), est un bon exemple.


53
Question du futur ... Et s'il n'y a pas de requête?
Sid

54
Question du présent. Et si jQuery est exagéré pour le projet en cours? (Ne pas assommer jQuery, utilisez-le moi-même. Parfois, vous ne voulez qu'une seule fonctionnalité d'une bibliothèque ..)
Bradmage

14
Lorsque vous dites "non pris en charge par IE", est-ce une vérité universelle, ou seulement vrai pour des versions spécifiques d'IE? Puisque beaucoup de choses ont changé dans le monde des navigateurs depuis que vous avez écrit cette réponse, il est peut-être temps de mettre à jour cette réponse?
Bryan Oakley

8
DOMContentLoaded est désormais pris en charge par IE9 et versions ultérieures: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam

6
Rapports de l'avenir, DOMContentLoaded est désormais pris en charge par tous les principaux navigateurs: caniuse.com/#feat=domcontentloaded
Jose Gómez

21

window.onloadpeut fonctionner sans corps. Créez une page avec uniquement les balises de script et ouvrez-la dans un navigateur. La page ne contient aucun corps, mais elle fonctionne toujours.

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>

6
Le HTML sans la balise body n'est pas valide si vous ajoutez réellement du contenu (qui devrait être dans une balise body). Il manque également un type à votre balise de script. Ne comptez jamais sur les navigateurs pour corriger votre code non conforme aux normes! (Comme les navigateurs peuvent le faire différemment ou pas du tout dans le passé ou le futur.)
Kissaki

4
@Kissaki: Le HTML standard n'a pas du tout besoin d'une balise body!
Robert Siemer

5
xhtml1 spécifie <!ELEMENT html (head, body)>[1] - et html401 spécifie également <!ELEMENT HTML O O (%html.content;)avec <!ENTITY % html.content "HEAD, BODY">[2]. html51 indique également le A head element followed by a body element.contenu 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-élément - Je suppose que toutes ces normes HTML communes / en cours d'utilisation ne nécessitent une étiquette de corps. :)
Kissaki

1
@Kissaki c'est du XHTML, pas du HTML. HTML permet l'omission de balises des balises corps de début et de fin, ainsi que l'omission des balises html et head, conformément à sa DTD SGML. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded

1
@Kissaki: html5 n'a plus besoin du type de script (si c'est javascript), vous avez raison pour les versions antérieures.
Mark

10

Je préfère, en général, ne pas utiliser l' <body onload=""événement>. Je pense qu'il est plus propre de séparer autant que possible les comportements du contenu.

Cela dit, il y a des occasions (généralement assez rares pour moi) où l'utilisation de la charge corporelle peut donner une légère augmentation de la vitesse.

J'aime utiliser Prototype donc je mets généralement quelque chose comme ça dans le <head> de ma page:

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

ou

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

Ce qui précède sont des astuces que j'ai apprises ici . J'aime beaucoup le concept d'attacher des gestionnaires d'événements en dehors du HTML.

(Modifier pour corriger une faute d'orthographe dans le code.)


À quelles occasions cela serait-il plus rapide et pourquoi?
Kissaki

Cette réponse semble très subjective avec tous les «je» («je préfère», «je pense»). Que s'il manque encore des faits objectifs et vérifiables, cela confirme à peu près cette impression.
Kissaki

1
Je prendrais cette réponse avec un grain de sel étant donné qu'elle a été publiée il y a plus de 6 ans. Vous êtes plus que bienvenus pour le mettre à jour ou publier votre propre réponse améliorée.
Mark Biek

7

'tant de réponses subjectives à une question objective. JavaScript "discret" est une superstition comme l'ancienne règle de ne jamais utiliser de gotos. Écrivez le code d'une manière qui vous aide à atteindre votre objectif de manière fiable, et non selon les croyances religieuses à la mode de quelqu'un.

Quiconque trouve:

 <body onload="body_onload();">

être trop distrayant est trop prétentieux et n'a pas ses priorités.

Normalement, je mets mon code JavaScript dans un fichier .js distinct, mais je ne trouve rien de compliqué à accrocher des gestionnaires d'événements en HTML, qui est d'ailleurs du HTML valide.


39
Il y a une bonne raison d'écrire du javascript discret. Supposons que vous ayez une application Web de 100 pages et que vous ayez utilisé la méthode <body onload = "body_onload ();"> au lieu de la placer dans le fichier javascript inclus par chaque page. Imaginez ensuite que vous deviez changer le nom de cette fonction pour une raison quelconque. Mettre l'événement dans le fichier javascript inclus 1) simplifie considérablement les modifications et 2) économise les ressources du serveur car les fichiers javascript peuvent être mis en cache pendant un an (sur un serveur correctement configuré) au lieu de télécharger le même code encore et encore.
Andrew Ensley

21
Donc, parce que vous ne prenez pas la peine d'apprendre pourquoi quelque chose est recommandé, vous étiquetez les recommandations "croyances religieuses à la mode" ??
hallvors

6
La question est "quelle est la différence entre ces deux méthodes?", Avec une demande de recommandation pour laquelle c'est mieux. Comment votre réponse répond-elle à cette question?
Richard Turner

1
Toute situation dans laquelle vous créez une solution modulaire en un seul endroit qui peut être appliquée à une grande masse de fichiers est bien meilleure que d'ajouter le code à chacune de la masse de fichiers elle-même. Il est préférable pour le temps de construction d'origine, pour des raisons d'organisation du code, pour la lisibilité et pour les modifications futures. Ce n'est pas à la mode, c'est en fait un concept plus ancien qui est présent dans des langages comme java et c ++ que les programmeurs Web adoptent maintenant comme la meilleure façon de coder.
Jimbo Jonny

1
Une bonne défense contre les attaques XSS dans les navigateurs modernes consiste à désactiver tous les javascript en ligne avec votre politique de sécurité du contenu. C'est une assez bonne raison de ne pas utiliser l'attribut onload dans votre code HTML.
Greg Ball

4

window.onload- Appelé après tous les fichiers DOM, JS, images, iframes, extensions et autres complètement chargés. Ceci est égal à $ (window) .load (function () {});

body onload=""- Appelé une fois DOM chargé. Ceci est égal à $ (document) .ready (function () {});


1
Est-ce que quelqu'un est capable de se procurer cela? J'ai vu cette déclaration sur de nombreux forums, mais jamais avec un lien vers l'endroit où elle est définie dans la spécification.
crempp le

1
@crempp Il y a l' élément body et les attributs globaux , donc je dirais que ce n'est pas vrai. Mais vous pouvez tester cela vous-même, voir jsbin.com/OmiViPAJ/1/edit . Là, vous pouvez voir que l'événement de chargement d'image est déclenché avant l'événement de chargement de corps.
Olaf Dietsche

2
Cette réponse contredit les autres; pouvez-vous fournir une source?
Jimmy Breck-McKye

2
api.jquery.com/ready La documentation jQuery indique: "La méthode .ready () est généralement incompatible avec l'attribut <body onload =" ">." Je pense que dans jQuery est plus proche de body.onload $ (window) .load (..) mais je pense qu'ils sont toujours différents.
ccsakuweb

2
Cette réponse est complètement fausse et ne devrait pas avoir de votes positifs. En fait, ce type de réponse est généralement cité comme étant parmi les plus grandes idées fausses sur les événements readyvs. se déclenche après le chargement de tout le document, y compris tous les scripts, images et feuilles de style. se déclenche après la construction de l'arborescence DOM mais avant les images, etc. Son équivalent est non . onloadloadDOMContentLoadedDOMContentLoadeddocument.readyload
rism

2

Il n'y a pas de différence ...

Donc, vous pouvez principalement utiliser les deux (un à la fois! -)

Mais pour des raisons de lisibilité et pour la propreté du code html, je préfère toujours le window.onload! O]


1

Si vous essayez d'écrire du code JS discret (et vous devriez l'être), vous ne devriez pas l'utiliser <body onload="">.

Je crois comprendre que différents navigateurs traitent ces deux types de façon légèrement différente, mais ils fonctionnent de manière similaire. Dans la plupart des navigateurs, si vous définissez les deux, l'un sera ignoré.


1

Pensez à la surcharge comme à tout autre attribut. Sur une zone de saisie, par exemple, vous pouvez mettre:

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

Ou vous pouvez appeler:

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

L'attribut onload fonctionne de la même manière, sauf qu'il prend une fonction comme valeur au lieu d'une chaîne comme le fait l'attribut value. Cela explique également pourquoi vous ne pouvez "utiliser qu'un seul d'entre eux" - l'appel de window.onload réattribue la valeur de l'attribut onload pour la balise body.

De plus, comme d'autres disent ici, il est généralement plus propre de garder le style et le javascript séparés du contenu de la page, c'est pourquoi la plupart des gens conseillent d'utiliser window.onload ou comme la fonction prête de jQuery.


1

<body onload = ""> devrait remplacer window.onload.

Avec <body onload = "">, document.body.onload peut être nul, non défini ou une fonction selon le navigateur (bien que getAttribute ("onload") devrait être quelque peu cohérent pour obtenir le corps de la fonction anonyme sous forme de chaîne) . Avec window.onload, lorsque vous lui affectez une fonction, window.onload sera une fonction cohérente dans tous les navigateurs. Si cela vous importe, utilisez window.onload.

window.onload est préférable pour séparer le JS de votre contenu de toute façon. Il n'y a pas beaucoup de raisons d'utiliser <body onload = ""> quand vous pouvez utiliser window.onload.

Dans Opera, la cible de l'événement pour window.onload et <body onload = ""> (et même window.addEventListener ("load", func, false)) sera la fenêtre au lieu du document comme dans Safari et Firefox. Mais, «ceci» sera la fenêtre à travers les navigateurs.

Cela signifie que, lorsque cela est important, vous devez envelopper le crud et rendre les choses cohérentes ou utiliser une bibliothèque qui le fait pour vous.


0

Ils fonctionnent tous les deux de la même façon. Cependant, notez que si les deux sont définis, un seul d'entre eux sera invoqué. J'évite généralement d'utiliser l'un ou l'autre directement. Au lieu de cela, vous pouvez attacher un gestionnaire d'événements à l'événement de chargement. De cette façon, vous pouvez intégrer plus facilement d'autres packages JS qui pourraient également avoir besoin d'attacher un rappel à l'événement onload.

Tout framework JS aura des méthodes multi-navigateurs pour les gestionnaires d'événements.


0

C'est un standard accepté que le contenu, la mise en page et le comportement soient séparés. Ainsi, window.onload () sera plus approprié à utiliser que <body onload="">si les deux font le même travail.


0

Désolé pour la réincarnation de ce fil après encore 3 ans de sommeil, mais j'ai peut-être enfin trouvé l'avantage indiscutable de window.onload=fn1;plus <body onload="fn1()">. Cela concerne les modules JS ou ES : lorsque votre onloadgestionnaire réside dans un fichier JS "classique" (c'est-à-dire référencé sans <script type="module" … >, dans les deux cas est possible; lorsque votre onloadgestionnaire réside dans un fichier JS "module" (c'est-à-dire référencé avec <script type="module" … >, le <body onload="fn1()">échouera avec "fn1 () n'est pas défini "erreur. La raison est peut-être que les modules ES ne sont pas chargés avant que HTML soit analysé ... mais c'est juste ma supposition. Quoi qu'il en soit, window.onload=fn1;fonctionne parfaitement avec les modules ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.