167 votes

Javascript - Comment détecter si le document est chargé (IE 7/Firefox 3)

Je veux appeler une fonction après le chargement d'un document, mais le document peut ou non avoir fini de se charger. S'il a été chargé, je peux simplement appeler la fonction. S'il n'a PAS été chargé, je peux attacher un écouteur d'événements. Je ne peux pas ajouter un écouteur d'événements après le déclenchement de onload, car il ne sera pas appelé. Alors comment puis-je vérifier si le document a été chargé ? J'ai essayé le code ci-dessous mais il ne fonctionne pas entièrement. Avez-vous une idée ?

var body = document.getElementsByTagName('BODY')[0];
// CONDITION DOES NOT WORK
if (body && body.readyState == 'loaded') {
    DoStuffFunction();
} else {
    // CODE BELOW WORKS
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

5 votes

"Je veux appeler une fonction après le chargement d'un document, mais le document peut ou non avoir fini de se charger." Cela ne fonctionne pas.

7 votes

Je pense qu'il veut dire qu'il n'a pas le contrôle du moment où son bloc de code est initialement exécuté, mais qu'il veut s'assurer que DoStuffFunction() n'est pas appelé avant la fin du chargement du document.

264voto

this.lau_ Points 23290

Il n'y a pas besoin de tout le code mentionné par galambalazs. La manière de le faire en JavaScript pur est simplement de tester document.readyState :

if (document.readyState === "complete") { init(); }

C'est également la façon dont jQuery procède.

Selon l'endroit où le JavaScript est chargé, cela peut se faire à l'intérieur d'un intervalle :

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        init();
    }
}, 10);

En fait, document.readyState peut avoir trois états :

Retourne "loading" pendant que le document est en train de se charger, "interactive" une fois qu'il a fini d'analyser mais qu'il charge encore les sous-ressources, et "complete" une fois qu'il a été chargé. -- document.readyState à Mozilla Developer Network

Donc si vous avez seulement besoin que le DOM soit prêt, vérifiez pour document.readyState === "interactive" . Si vous avez besoin que la page entière soit prête, y compris les images, vérifiez si document.readyState === "complete" .

3 votes

@costa, si document.readyState == "complete" cela signifie que tout, y compris les images, a été chargé.

0 votes

J'utilise une combinaison des deux événements et document.readyState pour s'assurer que la fonction démarre après l'analyse du DOM, ou plus tard, selon le moment où elle a été appelée. Existe-t-il un événement pour interactive readyState ?

0 votes

Génial - DOM est tellement trompeur.

32voto

galambalazs Points 24393

Pas besoin d'une bibliothèque. jQuery a utilisé ce script pendant un certain temps, btw.

http://dean.edwards.name/weblog/2006/06/again/

// Dean Edwards/Matthias Miller/John Resig

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // kill the timer
  if (_timer) clearInterval(_timer);

  // do stuff
};

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
  var script = document.getElementById("__ie_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init(); // call the onload handler
    }
  };
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
window.onload = init;

1 votes

Exactement ce que je cherchais - la fonction jQuery.ready sans la bibliothèque jQuery. Merci !

3 votes

Tu n'as pas du tout compris le sens de la question. init ne s'exécutera pas si le code que vous avez posté est inclus après que la page ait déjà été chargée, ce qui est le point de l'OP : il/elle ne peut pas contrôler quand son script est inclus. (notez que seul le setInterval branche fonctionnera)

3 votes

Il devrait être dans une bibliothèque. Avec toutes les autres roues que les gens réinventent couramment.

14voto

dan Points 468

Vous souhaitez probablement utiliser quelque chose comme jQuery, qui facilite la programmation JS.

Quelque chose comme :

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

Cela semble faire ce que vous recherchez.

2 votes

Et s'il veut voir comment jQuery le fait d'une manière portable, la source de jQuery est là pour l'inspection :-)

7 votes

Et au cas où ce ne serait pas clair, si ready() s'appelle après le chargement du document, la fonction passée est exécutée immédiatement.

2 votes

@Ben Blank : sauf bien sûr si jQuery lui-même est inclus après le chargement du document ;)

9voto

Jman Points 333
if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

0 votes

Cela ne semble pas fonctionner dans la dernière version de Chrome. document.loaded est toujours indéfini

0 votes

C'était en 2010 :). Maintenant, je vais utiliser body.readyState === 'loaded'

6voto

Nathan Stretch Points 507

Si vous voulez vraiment que ce code soit exécuté à charge pas à domready (c'est-à-dire que vous avez besoin que les images soient chargées également), alors malheureusement la fonction ready ne le fait pas pour vous. Je fais généralement quelque chose comme ça :

Inclure le javascript dans le document (c'est-à-dire toujours appelé avant le déclenchement du onload) :

var pageisloaded=0;
window.addEvent('load',function(){
 pageisloaded=1;
});

Puis votre code :

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}

(Ou l'équivalent dans votre framework de préférence.) J'utilise ce code pour faire du précaching de javascript et d'images pour les pages futures. Comme le contenu que je récupère n'est pas du tout utilisé pour cette page, je ne veux pas qu'il prenne le pas sur le téléchargement rapide des images.

Il y a peut-être un meilleur moyen, mais je ne l'ai pas encore trouvé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X