JavaScript-ドキュメントが読み込まれたかどうかを検出する方法(IE 7 / Firefox 3)


163

ドキュメントの読み込み後に関数を呼び出したいのですが、ドキュメントの読み込みがまだ完了していない場合があります。ロードされた場合は、関数を呼び出すだけです。ロードされなかった場合は、イベントリスナーをアタッチできます。onloadが呼び出されないため、onloadがすでに起動した後でeventlistenerを追加することはできません。では、ドキュメントが読み込まれたかどうかを確認するにはどうすればよいですか?以下のコードを試してみましたが、完全には機能しません。何か案は?

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
「ドキュメントの読み込み後に関数を呼び出したいのですが、ドキュメントの読み込みがまだ完了していない場合があります。」これは計算しません。
RichardSimões06年

7
彼は、彼のコードブロックが最初に実行されるタイミングを制御できないが、ドキュメントの読み込みが完了する前にDoStuffFunction()が呼び出されないようにする必要があることを意味します。
ベンブランク

回答:


257

galambalazsが言及しているすべてのコードは必要ありません。純粋なJavaScriptでそれを行うためのクロスブラウザーの方法は、単にテストすることdocument.readyStateです:

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

これは、jQueryが行う方法でもあります。

JavaScriptがロードされる場所に応じて、これはインターバル内で実行できます。

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

実際、document.readyState3つの状態があります。

ドキュメントの読み込み中は「読み込み中」を返し、解析が終了してサブリソースを読み込んでいる場合は「インタラクティブ」を返し、読み込みが完了したら「完了」を返します。- Mozillaの開発者向けネットワークでdocument.readystateで

したがって、DOMの準備だけが必要な場合は、を確認してくださいdocument.readyState === "interactive"。画像を含めてページ全体を準備する必要がある場合は、を確認してくださいdocument.readyState === "complete"


3
@costaは、document.readyState == "complete"画像を含むすべてが読み込まれたことを意味します。
ローラン2013年

私は両方のイベントの組み合わせを使用しdocument.readyStateており、DOMが解析された後、またはいつ呼び出されたかに応じて、関数が確実に開始するようにしています。インタラクティブな イベントはありreadyStateますか?
トマーシュZato -復活モニカ

3
使用します/loaded|complete/.test(document.readyState)。一部のブラウザdocument.readyStateは、「完全」ではなく「ロード」に設定されています。また、document.readyStateはフォントが読み込まれたことを保証しません。プラグインなしでそれをテストするための本当に良い方法はありません。
ライアンテイラー

2
どうdocument.onreadystatechangeですか?ブラウザがサポートしている場合、これはより合理化されたように見えます。stackoverflow.com/questions/807878/...

2
document.readyState !== "loading"「DOM準備完了」状態をチェックする方が良いと思います。これにより、readyState(「インタラクティブ」状態の後)が何らかの理由で遅くチェックされた場合に問題が発生するのを防ぎます。
rnevius

32

ライブラリは必要ありません。jQueryはしばらくの間、このスクリプトを使用していました。

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
まさに私が探していたもの-jQueryライブラリなしのjQuery.ready関数。ありがとう!
stricjux 2011

3
質問の要点を完全に逃しました。init投稿したこのコードがページの読み込み後に含まれている場合は実行されません。これがOPのポイントです。彼/彼女はスクリプトが含まれているときは制御できません。(setIntervalブランチのみが機能することに注意してください)
Roatin Marth 2012

3
これはライブラリに属しています。他のすべてのホイールと一緒に、人々は一般的に再発明します。
b01

14

おそらくjQueryのようなものを使用すると、JSプログラミングが簡単になります。

何かのようなもの:

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

あなたがしていることをやるようだ。


2
そして、jQueryがポータブルな方法でどのように実行するかを確認したい場合は、jQueryのソースを調べてください:-)
Thomas L Holaday

7
また、不明な場合ready()ドキュメントのロード後に呼び出され場合、渡された関数がすぐに実行されます。
ベンブランク

2
@Ben Blank:もちろん、ドキュメントのロード後にjQuery自体が含まれていない限り;)
Roatin Marth 2012

@Roatin Marth —実際、それもうまくいきます。(FF8とIE8のjQuery 1.7.1で試してみただけです。)
Ben Blank

35
-1:答えが理にかなっている場合でも、OPはjQueryについて言及していません。ドキュメントを準備するためだけにjQueryプロジェクト全体を使用することは、やり過ぎです。
marcgg 2013年

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

最新のChromeで動作しないように見えるのdocument.loadedは常に未定義です
Aniket

これは2010年でした:)。今、私は使用しますbody.readyState === 'loaded'
Jman

6

このコードをロード時に実行したい場合 domreadyではなくで(つまり、イメージもロードする必要がある場合)、残念ながらready関数はそれを行いません。私は一般的に次のようなことをします:

ドキュメントのJavaScriptに含める(つまり、onloadが起動する前に常に呼び出されます):

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

次に、コード:

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

(またはあなたの好みのフレームワークで同等のもの。)私はこのコードを使用して、将来のページのためにJavaScriptと画像の事前キャッシュを行います。取得したものはこのページではまったく使用されないので、画像の高速ダウンロードよりも優先されたくありません。

より良い方法があるかもしれませんが、私はそれをまだ見つけていません。


4

Mozila Firefoxは、これonreadystatechangeはに代わるものだと言っていDOMContentLoadedます。

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

DOMContentLoadedモジラのdocこう述べています。

DOMContentLoadedイベントは、スタイルシート、画像、サブフレームの読み込みが完了するのを待たずに、ドキュメントが完全に読み込まれて解析されたときに発生します(loadイベントは、完全に読み込まれたページを検出するために使用できます)。

loadイベントは完全なドキュメント+リソースの読み込みに使用する必要があると思います。


3

上記のJQueryを使用する方法が、最も簡単で、主に使用されています。ただし、純粋なjavascriptを使用できますが、最初に読み取られるように、このスクリプトをヘッドで定義してみてください。あなたが探しているのはwindow.onloadイベントです。

以下は、カウンターを実行するために作成した簡単なスクリプトです。その後、カウンタは10回の反復後に停止します

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

}

2

これを試して:

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);
    }
}

1

他の解決策があります。MyAppの新しいオブジェクトが作成されたときにアプリケーションを起動する必要があるため、次のようになります。

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');

私が知っているすべてのブラウザで動作しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.