window.onload vs document.onload

712

Quel est le plus largement pris en charge: window.onloadou document.onload?

Chris Ballance
la source
2
MDN docs explique ces windowévénements: onloadet DOMContentLoaded. Exemple d'utilisation:, window.addEventListener('DOMContentLoaded', callback). À partir de la mi-2019, compatible avec tous les principaux navigateurs. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks
Pour moi même encore, dans Firefox 75.0 aujourd'hui, window.onloadet document.onloadsont différents les uns des autres! window.onloadsemble avoir lieu après et a un peu plus chargé que document.onload! (Certaines choses fonctionnent avec une fenêtre qui ne fonctionne pas avec le document! Cela vaut également pour document.onreadstatechange 'complete'!)
Andrew

Réponses:

723

Quand tirent-ils?

window.onload

  • Par défaut, il est déclenché lors du chargement de la page entière, y compris son contenu (images, CSS, scripts, etc.).

Dans certains navigateurs, il prend désormais en charge le rôle de document.onloadet se déclenche lorsque le DOM est également prêt.

document.onload

  • Il est appelé lorsque le DOM est prêt, ce qui peut être antérieur aux images et à tout autre contenu externe chargé.

Dans quelle mesure sont-ils pris en charge?

window.onloadsemble être le plus largement soutenu. En fait, certains des navigateurs les plus modernes ont en quelque sorte remplacé document.onloadpar window.onload.

Les problèmes de prise en charge du navigateur sont probablement la raison pour laquelle de nombreuses personnes commencent à utiliser des bibliothèques telles que jQuery pour gérer la vérification du document en cours de préparation, comme suit:

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

Aux fins de l'histoire. window.onloadvs body.onload:

Une question similaire a été posée il y a quelque temps sur les forums de codage concernant l'utilisation de window.onloadover body.onload. Le résultat semblait être que vous devriez utiliser window.onloadcar il est bon de séparer votre structure de l'action.

Josh Mein
la source
25
En fait, cette affirmation semble viser un choix entre window.onloadet <body onload="">qui est complètement différent (et la "structure distincte de l'action" a beaucoup plus de sens dans ce contexte). Non pas que la réponse soit fausse, mais la base en est.
Thor84no
2
Cette citation est grammaticalement horrible ... une édition (marquée) ne devrait-elle pas aider?
Kheldar
@ Thor84no J'ai enfin trouvé le temps de regarder. J'ai apporté quelques améliorations.
Josh Mein
@Kheldar J'ai décidé de paraphraser la citation car elle était plutôt approximative.
Josh Mein
@JoshMein Cela signifie-t-il que document.onloadJS est équivalent à jQuery document.ready?
john cj
276

L'idée générale est que window.onload se déclenche lorsque la fenêtre du document est prête pour la présentation et document.onload se déclenche lorsque l' arborescence DOM (créée à partir du code de balisage dans le document) est terminée .

Idéalement, la souscription aux événements de l'arborescence DOM permet des manipulations hors écran via Javascript, n'encourageant presque aucune charge CPU . Au contraire, cela window.onloadpeut prendre un certain temps à se déclencher , lorsque plusieurs ressources externes doivent encore être demandées, analysées et chargées.

► Scénario de test:

Pour observer la différence et la façon dont votre navigateur de choix implémente les gestionnaires d'événements susmentionnés , insérez simplement le code suivant dans la <body>balise - - de votre document .

<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>

►Résultat:

Voici le comportement résultant, observable pour Chrome v20 (et probablement la plupart des navigateurs actuels).

  • Aucun document.onloadévénement.
  • onloadse déclenche deux fois lorsqu'il est déclaré à l'intérieur du <body>, une fois lorsqu'il est déclaré à l'intérieur du <head>(où l'événement agit alors comme document.onload).
  • compter et agir en fonction de l'état du compteur permet d'émuler les deux comportements événementiels.
  • Vous pouvez également déclarer le window.onloadgestionnaire d'événements dans les limites de l' <head>élément HTML .

►Exemple de projet:

Le code ci-dessus est tiré de la base de code de ce projet ( index.htmlet keyboarder.js).


Pour une liste des gestionnaires d'événements de l'objet window , reportez-vous à la documentation MDN.

Lorenz Lo Sauer
la source
143

Ajouter un écouteur d'événements

<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 vanille

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


2 jQuery

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


Bonne chance.

Akash
la source
14
"L'événement DOMContentLoaded est déclenché lorsque le document HTML initial a été complètement chargé et analysé, sans attendre la fin du chargement des feuilles de style, des images et des sous-trames." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Vous semblez donc être incorrect sur tout ce qui est chargé lors de cet événement.
ProfK
2
@ProfK, merci pour vos commentaires. Pouvez-vous essayer window.addEventListener('load', function() {...}). J'ai également mis à jour ma réponse.
Akash
4
Ce que j'aime dans cette réponse, c'est qu'elle donne une solution tout simplement ancienne-javascript. Vous penseriez que la plupart des gens pensent que jQuery est intégré à tous les navigateurs, étant donné la fréquence à laquelle il est donné comme seule réponse.
Dave Land
Double problème lorsque le fichu jquery prend trop de temps à charger et que vous obtenez $ introuvable. Je suis d'avis que les solutions de type $ (window) .ready ne doivent JAMAIS être approuvées pour fonctionner.
Shayne
1
J'ai essayé les deux dans le chrome d'aujourd'hui. Il n'attend pas les css et les polices.
movAX13h
78

Selon l' analyse des documents HTML - La fin ,

  1. Le navigateur analyse la source HTML et exécute des scripts différés.

  2. A DOMContentLoadedest distribué au documentmoment où tout le code HTML a été analysé et exécuté. L'événement bouillonne au window.

  3. Le navigateur charge des ressources (comme des images) qui retardent l'événement de chargement.

  4. Un loadévénement est envoyé au window.

Par conséquent, l'ordre d'exécution sera

  1. DOMContentLoadedauditeurs d'événements windowdans la phase de capture
  2. DOMContentLoaded auditeurs d'événements document
  3. DOMContentLoadedauditeurs d'événements windowdans la phase de bulle
  4. loadécouteurs d'événements (y compris le onloadgestionnaire d'événements) dewindow

Un loadécouteur d'événement bulle (y compris le onloadgestionnaire d'événements) dans documentne doit jamais être invoqué. Seuls les loadécouteurs de capture peuvent être invoqués, mais en raison de la charge d'une sous-ressource comme une feuille de style, et non en raison de la charge du document lui-même.

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
la source
J'ai exécuté votre extrait de code et document - load - capturecela arrive, ce qui est contraire à ce que j'attendais dans ma recherche pour savoir pourquoi le chargement de documents ne se produit pas pour moi. Bizarrement, c'est incohérent. Parfois, cela apparaît, parfois non, parfois deux fois - mais cela n'arrive jamais document - load - bubble. Je suggère de ne pas utiliser document load.
erreur
@erroric Bon point. Je n'ai pas considéré qu'un loadévénement est distribué sur des ressources externes. Cet événement ne bouillonne pas, il n'est donc généralement pas détecté sur le document, mais il devrait l'être lors de la phase de capture. Ces entrées font référence à la charge des éléments <style>et <script>. Je pense qu'Edge a raison de les montrer, et Firefox et Chrome ont tort.
Oriol
Merci Oriol, l' useCaptureoption m'a appris quelque chose de nouveau.
Paul Watson
Merci d'avoir résumé le flux d'analyse et de rendu de w3. Je me demande juste après l'étape 4 une fois l'événement 'load' déclenché, que peut-il se passer d'autre? J'ai remarqué sur mon navigateur que parfois certains objets sont toujours récupérés après le déclenchement de l'événement de chargement, même si je n'ai pas du tout touché ou interagi avec la page. Savez-vous comment s'appellent ces objets? «Objets de rendu non bloquants?
weefwefwqg3
12

Dans Chrome, window.onload est différent de <body onload="">, alors qu'ils sont les mêmes dans Firefox (version 35.0) et IE (version 11).

Vous pouvez l'explorer par l'extrait de code suivant:

<!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>

Et vous verrez à la fois "fenêtre chargée" (qui vient en premier) et "body onload" dans la console Chrome. Cependant, vous ne verrez que "onload du corps" dans Firefox et IE. Si vous exécutez " window.onload.toString()" dans les consoles d'IE & FF, vous verrez:

"fonction onload (événement) {bodyOnloadHandler ()}"

ce qui signifie que l'affectation "window.onload = function (e) ..." est écrasée.

VincentZHANG
la source
6

window.onloadet onunloadsont des raccourcis vers document.body.onloadetdocument.body.onunload

document.onloadet le onloadgestionnaire sur toutes les balises html semble être réservé mais jamais déclenché

' onload' dans le document -> true

garaboncias
la source
5

window.onload cependant ils sont souvent la même chose. De même, body.onload devient window.onload dans IE.

AnthonyWJones
la source
1

Window.onload est la norme, cependant - le navigateur Web de la PS3 (basé sur Netfront) ne prend pas en charge l'objet window, vous ne pouvez donc pas l'utiliser là-bas.

gotofritz
la source
0

En bref

  • windows.onloadn'est pas pris en charge par IE 6-8
  • document.onload n'est pris en charge par aucun navigateur moderne (l'événement n'est jamais déclenché)

Kamil Kiełczewski
la source