DOMContentLoaded事件とそのカプセル化方法について話します.


私たちは開発に際して、常にページのロードが完了したかどうかを確認し、スクリプトの安全運行を確保する必要があります.以下では、ページのロードが完了したかどうかを確認するイベントについて話してみます.
1.onload事件
ページのすべてのリソースのロードが完了すると、windowオブジェクトにonloadイベントがトリガされます.イベントは通常、論理コードを実行するために使用される.例えば、JSを通じてDOMを訪問する必要があります.

    console.log(document.getElementById('name').innerHTML);

chengxuyuan
上記のコードの実行時には間違いがあります.スクリプト実行時には、IDがnameであるdivはまだロードされていません.では、私たちがDOM文書を獲得するときはいつが確実ですか?上記のonloadでは、ページのonloadがトリガされたとき、ページドキュメントのストリーム及びリソースが完全にロードされたことを証明します.このとき、ドキュメントフローにおけるDOMを取得することは、最も安全なタイミングです.上記のコードを改造します.以下の通りです.

    window.onload = function () {
        console.log(document.getElementById('myname').innerHTML);
    }

chengxuyuan
再度実行すると、コードは間違えません.したがって、onloadイベントの実際の効果は、ページがDOMツリーを解析し終わったときに、すべてのピクチャ、スタイルテーブル、スクリプトなどのリソースのローディングが完了した後にトリガされる.この問題は、リソースが多すぎると、onloadに深刻な遅延問題が発生し、ユーザ体験に深刻な影響を与える.
2.DOMContentLoaded事件
上記の場合に比べて、FirefoxのDOMContentLoadedイベントはより合理的であり、この方法がトリガする時間はより早く、DOMコンテンツのロードが完了するとトリガされ、他のリソースのロードが完了するまで待つ必要はない.

    window.onload = function () {
        console.log('          ');
    }
    document.addEventListener("DOMContentLoaded", function(event) {
        console.log('DOM         ');
    });
上記コードの実行結果は順次印刷されます.
DOMはすでに完全にページリソースをロードして解析しました.すべてのロードが完了しました.
これにより、DOMContentLoadedイベントは、より早くDOMロードの完了を捉えることができる.
現在、Webkit 525以上のバージョンとOperaもこの方法を含んでいます.また、HTML 5で標準化されています.しかし、IEはまだDOMContentLoadedをサポートしていない.
また、多くのJavaScriptフレームにはdocument.ready機能があります.例えば、jQueryのようなものです.
$(document).ready(function(){});
その核心はDOMContentLoaded事件です.
document.addEventListener("DOMContentLoaded",function(){...},false);
イベントバインディングを行うが、IEに対して互換性のある処理が必要である.
3.onreadystatechange事件
IEはDOMContentLoadedをサポートしていないが、onreadystatechangeイベントをサポートしており、イベントの目的は、ドキュメントまたは要素のロード状態に関する情報を提供することである.onreadystatechangeイベントをサポートする各オブジェクトは、次の5つの値のうちの1つを含むことができるreadyState属性を有する.
  • uninitialized(初期化):オブジェクトは存在するが、初期化されていない.
  • loading(ロード中):オブジェクトはデータをロードしています.
  • loaded(ロード完了):オブジェクトローディングデータが完了しました.
  • interactive(インタラクション):オブジェクトを操作できますが、まだ完全にロードされていません.
  • complete(完了):オブジェクトはすでにロード済みです.
  • onreadystatechangeイベントは、DOMロードが完了したかどうかを検出するために使用でき、document.readyState == 'complete'の場合、DOMロードが完了したことを示す.しかし、ページにiframeがあると、iframeのすべてのリソースがロードされてからcompleteになります.この時もホームページ面の遅延が発生しました.また、試験された場合、ページにiframeがなくても、この方式はonloadに相当し、すべてのリソースがダウンロードされた後にトリガされる.
    4.doScrroll方法
    しかし、IEは、間隔を介して呼び出しられる特有の方法doScrollがある.
    document.documentElement.doScroll("left");
    
    DOMがロードされたかどうかを検出することができます.ページがロードされていない場合、この方法は、doScrollがエラーを報告しない限り、DOMロードが完了したことを表します.この方法はDOMContentLoadedの実装に近い.
    5.JavascriptパッケージDOMContentLoaded事件
    以下は、JSパッケージDOMContentLoadedイベントであり、良好な互換性を達成するための簡単なコード実装である.
    function ready(fn){
    
        //   Mozilla、Opera webkit 525+    DOMContentLoaded  
        if(document.addEventListener) {
            document.addEventListener('DOMContentLoaded', function() {
                document.removeEventListener('DOMContentLoaded',arguments.callee, false);
                fn();
            }, false);
        } 
    
        //   IE
        else if(document.attachEvent) {
            //        iframe    ,          
            document.attachEvent('onreadystatechange', function() {
                if(document.readyState == 'complete') {
                    document.detachEvent('onreadystatechange', arguments.callee);
                    fn();
                }
            });
    
            //    IE     iframe  ,    doScroll     DOM      
            if(document.documentElement.doScroll && typeof window.frameElement === "undefined") {
                try{
                    document.documentElement.doScroll('left');
                }
                catch(error){
                    return setTimeout(arguments.callee, 20);
                };
                fn();
            }
        }
    };
    IEについては、まずdocumentonreadystatechangeイベントを登録する.これは、ページがiframeにあるとき、doScroll方法が失敗することを避けるためであり、実現コードにおいて判断された.その後、IEであり、ページがiframeにないと判断された場合、setTimeoutによって継続的に起動される.
    document.documentElement.doScroll('left');
    呼び出しが成功するまでは、DOMロードが完了しました.
    まとめてみますと、開発時には、DOMContentLoadedイベントをカプセル化して、ページDOMのロードが完了したかどうかを検出し、その後、論理コードを実行して、ユーザー体験を向上させます.