ページ DOM がロードされたとき (ただし window.onload 前) に通知を受け取る

StackOverflow https://stackoverflow.com/questions/65434

  •  09-06-2019
  •  | 
  •  

質問

ページ本文が読み込まれたとき(すべての画像とサードパーティのリソースが読み込まれる前に、 window.onload イベント)ですが、ブラウザごとに異なります。

すべてのブラウザでこれを行うための決定的な方法はありますか?

これまでのところ、私が知っているのは次のとおりです。

  • DOMコンテンツロード済み :Mozilla、Opera 9、および最新の WebKits 上。これには、イベントにリスナーを追加することが含まれます。

    document.addEventListener( "DOMContentLoaded", [初期化関数], false );

  • 遅延スクリプト:IE では、@defer 属性を使用して SCRIPT タグを発行できます。このタグは、BODY タグが閉じられた後にのみ確実に読み込まれます。

  • ポーリング:他のブラウザではポーリングを続けることができますが、ポーリングするための標準的なものはありますか、それともブラウザごとに異なることを行う必要がありますか?

document.write や外部ファイルを使用せずにできるようにしたいと考えています。

これは jQuery を介して簡単に実行できます。

$(document).ready(function() { ... })

しかし、私は JS ライブラリを作成しているので、jQuery が常にそこにあるとは期待できません。

役に立ちましたか?

解決

DOM の準備ができているかどうかを確認するためのブラウザーをまたいだ方法はありません。これが、厄介な非互換性の部分を抽象化するために、jQuery のようなライブラリが存在する理由です。

Mozilla、Opera、および最新の WebKit は、 DOMContentLoaded イベント。IE と Safari では、ウィンドウをスクロールしたり、スタイルシートをチェックしたりするなど、奇妙なハックが必要です。悲惨な詳細は jQuery に含まれています bindReady() 関数。

他のヒント

このページを見つけました。このページには、コンパクトな自己完結型ソリューションが示されています。すべてのブラウザで動作するようで、その方法についての説明があります。

http://www.kryogenix.org/days/2007/09/26/shortloaded

YUI はこれを行うために 3 つのテストを使用します。Firefox と最近の WebKit では、DOMContentLoaded イベントが発生します。古い Safari では、document.readyState は「ロード済み」または「完了」になるまで監視しました。IE の場合、HTML <P> タグが作成され、DOM の準備ができていない場合にエラーが発生する「doScroll()」メソッドが呼び出されます。のソース YAHOO.util.イベント YUI 固有のコードを示します。Event.js で「doScroll」を検索します。

jQuery のようなライブラリを使用すると、ブラウザの不一致に費やす膨大な時間を節約できます。

この場合、jQuery を使用すると、次のようにすることができます。

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

興味があればソースを見て、それがどのように行われるかを確認することができますが、ライブラリ作成者がすべての面倒な作業をすべて行ってくれているのに、この時代では誰もこの車輪を再発明すべきではないと思います。

jQuery から関連するコード部分を取得するだけです。John Resig は、この問題の基礎のほとんどをすでに jQuery でカバーしています。

なぜこうしないのか:

<body>  
  <!-- various content -->  
  <script type="text/javascript">  
  <!--  
    myInit();  
  -->
  </script>  
</body>  

私が物事を正しく理解していれば、ブラウザがページ内で myInit をヒットするとすぐに myInit が実行されます。これは本文の最後の部分です。

あなたが探している派手なクロスブラウザ ソリューションは存在しません...(大勢の群衆が「ああああ....」と言っている音を想像してください)。

DomContentLoaded 単にあなたのベストショットです。まだ必要です polling IE オールディーズ向けのテクニック。

  1. addEventListener を使用してみてください。
  2. 利用できない場合 (当然 IE)、フレームを確認します。
  3. フレームでない場合は、エラーがスローされなくなるまでスクロールします (ポーリング)。
  4. フレームの場合は、IE イベント document.onreadystatechange を使用します。
  5. その他の非サポートブラウザの場合は、古い document.onload イベントを使用してください。

次のコードサンプルを見つけました javascript.info これを使用すると、すべてのブラウザをカバーできます。

function bindReady(handler){

    var called = false

    function ready() { 
        if (called) return
        called = true
        handler()
    }

    if ( document.addEventListener ) { // native event
        document.addEventListener( "DOMContentLoaded", ready, false )
    } else if ( document.attachEvent ) {  // IE

        try {
            var isFrame = window.frameElement != null
        } catch(e) {}

        // IE, the document is not inside a frame
        if ( document.documentElement.doScroll && !isFrame ) {
            function tryScroll(){
                if (called) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 10)
                }
            }
            tryScroll()
        }

        // IE, the document is inside a frame
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }

    // Old browsers
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    else {
        var fn = window.onload // very old browser, copy old onload
        window.onload = function() { // replace by new onload and call the old one
            fn && fn()
            ready()
        }
    }
}

これはかなりうまくいきます:

setTimeout(MyInitFunction, 0);

setTimeout の使用は非常にうまく機能しますが、いつ実行されるかはブラウザ次第です。タイムアウト時間としてゼロを渡すと、ブラウザは状況が「解決」されたときに実行されます。

これの良い点は、多数のイベントを保持でき、onLoad イベントの連鎖について心配する必要がないことです。

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

これらはすべて、ドキュメントの読み込みが完了したときに実行されます。ドキュメントの読み込み後に設定した場合は、スクリプトの実行が終了した後に実行されます。

実行順序は決まっておらず、ブラウザごとに変わる可能性があります。だから当てにならないんだよ myFunction 前に走られる anotherFunction 例えば。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top