web-dev-qa-db-ja.com

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

ドキュメントの読み込み後に関数を呼び出したいのですが、ドキュメントの読み込みが完了しているかどうかは不明です。ロードされた場合、関数を呼び出すことができます。ロードされなかった場合は、イベントリスナーをアタッチできます。 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);
    }
}
154
Marcos

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

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

これもjQueryが行う方法です。

JavaScriptのロード場所に応じて、これは間隔内で実行できます。

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

実際、document.readyStateには3つの状態があります。

ドキュメントの読み込み中は「読み込み中」、解析が終了してもサブリソースの読み込みが完了すると「インタラクティブ」、読み込みが完了すると「完了」を返します。 - Mozilla Developer Networkのdocument.readyState

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

242
laurent

ライブラリは必要ありません。 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;
32
gblazex

あなたはおそらくjQueryのようなものを使いたいと思うでしょう。これはJSプログラミングを容易にします。

何かのようなもの:

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

あなたが望んでいることをするようだ.

15
dan

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

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

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

次に、コード:

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

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

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

5
Nathan Stretch
if(document.loaded) {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}
4
Jman

Mozila Firefoxは、onreadystatechangeDOMContentLoadedの代替であると言っています。

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

DOMContentLoadedには、Mozilaのドキュメントによると:

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

loadイベントは、完全なドキュメントとリソースの読み込みに使用されるべきだと思います。

3
Mostafa Talebi

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

}
3
Talha

これを試して:

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

私には他の解決策があります。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');

それは私が知っていること、すべてのブラウザで動作しています。

1
vitus