Javascript - So erkennen Sie, ob ein Dokument geladen wurde (IE 7 / Firefox 3)

163

Ich möchte eine Funktion aufrufen, nachdem ein Dokument geladen wurde, aber das Dokument wurde möglicherweise noch nicht vollständig geladen. Wenn es geladen wurde, kann ich einfach die Funktion aufrufen. Wenn es NICHT geladen wurde, kann ich einen Ereignis-Listener anhängen. Ich kann keinen Ereignislistener hinzufügen, nachdem der Onload bereits ausgelöst wurde, da er nicht aufgerufen wird. Wie kann ich also überprüfen, ob das Dokument geladen wurde? Ich habe den folgenden Code ausprobiert, aber er funktioniert nicht ganz. Irgendwelche Ideen?

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);
    }
}
Marcos
quelle
5
"Ich möchte eine Funktion aufrufen, nachdem ein Dokument geladen wurde, aber das Dokument wurde möglicherweise noch nicht vollständig geladen." Dies wird nicht berechnet.
Richard Simões
7
Ich glaube, er meint, er habe keine Kontrolle darüber, wann sein Codeblock zum ersten Mal ausgeführt wird, möchte aber sicherstellen, dass DoStuffFunction () nicht aufgerufen wird, bevor das Dokument vollständig geladen wurde.
Ben Blank

Antworten:

257

Der gesamte von Galambalazs erwähnte Code ist nicht erforderlich. Der browserübergreifende Weg, dies in reinem JavaScript zu tun, besteht einfach darin, Folgendes zu testen document.readyState:

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

So macht es auch jQuery.

Je nachdem, wo das JavaScript geladen ist, kann dies innerhalb eines Intervalls erfolgen:

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

In der Tat document.readyStatekann drei Zustände haben:

Gibt "Laden" zurück, während das Dokument geladen wird, "Interaktiv", sobald das Parsen abgeschlossen ist, aber immer noch Unterressourcen geladen werden, und "Fertig", sobald es geladen wurde. - document.readyState im Mozilla Developer Network

Wenn Sie also nur das DOM benötigen, um bereit zu sein, suchen Sie nach document.readyState === "interactive". Wenn Sie die gesamte Seite einschließlich der Bilder benötigen, suchen Sie nach document.readyState === "complete".

Laurent
quelle
3
@costa, wenn document.readyState == "complete", bedeutet dies, dass alles, einschließlich Bilder, geladen wurde.
Laurent
Ich verwende eine Kombination beider Ereignisse und document.readyStateum sicherzustellen, dass die Funktion nach dem Parsen von DOM oder später gestartet wird, je nachdem, wann es aufgerufen wurde. Gibt es eine Veranstaltung für interaktive readyState ?
Tomáš Zato - Wiedereinsetzung Monica
3
Ich würde verwenden /loaded|complete/.test(document.readyState). Einige Browser sind document.readyStateauf "geladen" anstatt auf "vollständig" eingestellt. Außerdem stellt document.readyState NICHT sicher, dass Schriftarten geladen wurden. Ohne Plugin gibt es keine wirklich gute Möglichkeit, dies zu testen.
Ryan Taylor
2
Was ist mit document.onreadystatechange? Dies scheint rationaler zu sein, wenn Browser dies unterstützen. stackoverflow.com/questions/807878/…
2
Ich denke, es wäre besser document.readyState !== "loading", nach dem Status "DOM bereit" zu suchen. Dies verhindert, dass Probleme auftreten, wenn das readyStateaus irgendeinem Grund zu spät überprüft wird (nach dem Status "Interaktiv").
Rnevius
32

Keine Notwendigkeit für eine Bibliothek. jQuery hat dieses Skript übrigens eine Weile verwendet.

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;
gblazex
quelle
1
Genau das, wonach ich gesucht habe - jQuery.ready funktioniert ohne die jQuery-Bibliothek. Danke!
Stricjux
3
Ich habe den Punkt der Frage total verpasst. initwird nicht ausgeführt, wenn dieser von Ihnen veröffentlichte Code enthalten ist, nachdem die Seite bereits geladen wurde. Dies ist der Punkt des OP: Er kann nicht steuern, wann sein Skript enthalten ist. (Beachten Sie, dass nur der setIntervalZweig funktioniert)
Roatin Marth
3
Dies gehört in eine Bibliothek. Zusammen mit all den anderen Rädern erfinden die Leute gewöhnlich neu.
B01
14

Sie möchten wahrscheinlich so etwas wie jQuery verwenden, was die JS-Programmierung erleichtert.

Etwas wie:

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

Scheint zu tun, was Sie suchen.

Dan
quelle
2
Und wenn er sehen will, wie jQuery es auf tragbare Weise macht, ist jQuerys Quelle für die Inspektion da :-)
Thomas L Holaday
7
Und falls nicht klar ist, ob die übergebene Funktion nach dem Laden des Dokuments ready()aufgerufen wird , wird sie sofort ausgeführt.
Ben Blank
2
@ Ben Blank: es sei denn natürlich, jQuery selbst ist enthalten, nachdem das Dokument geladen wurde;)
Roatin Marth
@ Roatin Marth - Eigentlich funktioniert das auch gut. (Ich habe es gerade mit jQuery 1.7.1 auf FF8 und IE8 versucht.)
Ben Blank
35
-1: Auch wenn die Antwort sinnvoll ist, hat das OP jQuery nie erwähnt. Die Verwendung des gesamten jQuery-Projekts, um das Dokument fertig zu stellen, ist weitaus übertrieben.
Marcgg
8
if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}
Jman
quelle
Scheint nicht in der neuesten Chrome zu funktionieren document.loadedist immer undefiniert
Aniket
das war 2010 :). Jetzt werde ich verwendenbody.readyState === 'loaded'
Jman
6

Wenn Sie möchten, dass dieser Code beim Laden ausgeführt wird , nicht beim Domready (dh Sie müssen auch die Bilder laden), dann erledigt die Ready-Funktion dies leider nicht für Sie. Ich mache im Allgemeinen einfach so etwas:

In Dokument-Javascript aufnehmen (dh immer aufgerufen, bevor Onload ausgelöst wird):

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

Dann dein Code:

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

(Oder das Äquivalent in Ihrem bevorzugten Rahmen.) Ich verwende diesen Code, um Javascript und Bilder für zukünftige Seiten vorzuspeichern. Da das, was ich bekomme, für diese Seite überhaupt nicht verwendet wird, möchte ich nicht, dass es Vorrang vor dem schnellen Herunterladen von Bildern hat.

Es mag einen besseren Weg geben, aber ich muss ihn noch finden.

Nathan Stretch
quelle
4

Mozila Firefox sagt, das onreadystatechangesei eine Alternative zu DOMContentLoaded.

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}

Im DOMContentLoadedMozila-Dokument heißt es:

Das DOMContentLoaded-Ereignis wird ausgelöst, wenn das Dokument vollständig geladen und analysiert wurde, ohne darauf zu warten, dass Stylesheets, Bilder und Unterrahmen vollständig geladen sind (das Ladeereignis kann zum Erkennen einer vollständig geladenen Seite verwendet werden).

Ich denke, loadEreignis sollte für ein vollständiges Laden von Dokumenten + Ressourcen verwendet werden.

Mostafa Talebi
quelle
3

Das obige mit JQuery ist der einfachste und am häufigsten verwendete Weg. Sie können jedoch reines Javascript verwenden, aber versuchen Sie, dieses Skript im Kopf so zu definieren, dass es am Anfang gelesen wird. Was Sie suchen, istwindow.onload Veranstaltung.

Unten ist ein einfaches Skript, das ich erstellt habe, um einen Zähler auszuführen. Der Zähler stoppt dann nach 10 Iterationen

window.onload=function()
{
    var counter = 0;
    var interval1 = setInterval(function()
    { 
        document.getElementById("div1").textContent=counter;
        counter++; 
        if(counter==10)
        {
            clearInterval(interval1);
        }
    },1000);

}
Talha
quelle
2

Versuche dies:

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

Ich habe eine andere Lösung. Meine Anwendung muss gestartet werden, wenn ein neues Objekt von MyApp erstellt wird. Es sieht also so aus:

function MyApp(objId){
     this.init=function(){
        //.........
     }
     this.run=function(){
          if(!document || !document.body || !window[objId]){
              window.setTimeout(objId+".run();",100);
              return;
          }
          this.init();
     };
     this.run();
}
//and i am starting it 
var app=new MyApp('app');

Es funktioniert in allen Browsern, die ich kenne.

Vitus
quelle