web-dev-qa-db-ja.com

DOMContentLoadedイベントはjQueryの.ready()関数とまったく同じですか?

window.addEventListener('DOMContentLoaded', function() {});をjQueryの$(document).bind('ready', function() {});に置き換えました。最初のものがIE <9で動作しなかったため、.attachEvent()ダミーブラウザーの場合、jQuery自体でうまくカバーできれば。

置換後間もなく、ページのロード/更新後少なくとも0〜2ミリ秒でDOMContentLoadedイベントが発生することに気付きました(少なくともこれはログスクリプトによってログに記録されたものです)が、.ready()は常にページの更新後、少なくとも15〜20ミリ秒が発生します(再び-スクリプトによって記録されます)。

私は純粋に私の好奇心を養うことを求めています、なぜそのような「重要な」遅延があるのですか?もちろん、jQueryが後でそのイベントを起動するということは、私にとっては問題ありません。ただ、すべての答えを知りたい(そして世界を支配している!:])ので、私はそれで眠れません! :]

[〜#〜] edit [〜#〜]:in 。ready()function doc some user(Nick(of Nexxar))は次のように指摘しています:「jQueryはIEに存在しない「DOMContentLoaded」イベントをシミュレートしますが、使用されたメカニズムは他のブラウザで使用されたイベントよりもずっと後に起動します)。おそらくこれは同じです、私は求めていますか?

33
trejder

イベントをサポートするブラウザーを想定:

  1. 実際のイベントは、任意のdocumentをサポートできます。 jQueryは、何を渡しても、ロードされたdocumentのみを使用します。
  2. イベントが既に発生している場合でも、jQueryはイベントを非同期的に発生させます。イベントが既に発生している場合、'DOMContentLoaded'イベントをアタッチしても何も実行されません。

これらのブラウザーに遅延はありません。 http://jsfiddle.net/rqTAX/3/ (ログに記録されるオフセットはミリ秒単位です)を参照してください。

このイベントをサポートしていないブラウザの場合、jQueryも明らかにそれらに対して機能します。本物のDOMContentLoadedとは異なるハッキングメカニズムを使用し、本物のDOMContentLoadedがすぐに起動するとは限りません。

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }

    try {
        // If IE is used, use the trick by Diego Perini
        // http://javascript.nwbox.com/IEContentLoaded/
        document.documentElement.doScroll("left");
    } catch(e) {
        setTimeout( doScrollCheck, 1 );
        return;
    }

    // and execute any waiting functions
    jQuery.ready();
}
21
Esailija

jQueryは、documentreadystatechangeイベントにバインドすることにより、このイベントをシミュレートします。これは、oldIEでDOMContentLoadedをシミュレートする標準的な方法です。

jQueryソースによると 、そのイベントは「遅延」を引き起こしますが、window.onload。ただし、そのイベントが正確に発生するwhenが見つかりません。 DOMContentLoadedは、DOMが構築され、スクリプトの準備ができると起動します。したがって、readystatechangeafterを起動します。おそらく、それはレイアウトのレンダリングやそのようなスタイリングを待っていますか、それともレンダリング/レイアウトプロセスの後半でイベントがトリガーされますか?

とにかく、afterDOMContentLoadedが発生する可能性があります。おそらくIEがdocumentreadyStateを「完了」します。

(誰かが明確な答えを持っている場合、コメントを投稿し、この答えを更新します。正確にいつ自分が発動するのかを知りたいです、そして私はどんなドキュメントでも、私が望むようなサイトでもその答えを見つけることができません互換モード。)

4
ajm

「準備完了」が後で(実際には)発生するように見えるもう1つの理由は、多くのイベントが接続されている可能性があることです。これらのいずれかが長時間実行されている同期操作である場合、readyイベントはかなり後で発生します。たとえば、私はknockout.jsを使用し、ページを初期化するのに500msかかることがあります。


ただし、最小限のテストページを使用することは当然のことではありません。私は次を実行しようとしました:

 console.log(window.performance.timing.domContentLoadedEventEnd -
             window.performance.timing.domContentLoadedEventStart);

これにより、単純なスーパーページでも約6ミリ秒が得られます


また、私はあなたのコードを受け取って、Chromeのパフォーマンスツールを実行し、いくつかの興味深いことを発見しました。

enter image description here

  • ところで:垂直の青いバーはDOMCONTENTLOADEDで、緑は「最初のペイント」です
  • DOMCONTENTLOADEDイベントでの非常に単純な関数呼び出しだけでも5ミリ秒かかることがあります(これはi7で行われます)。解析する必要があり、初期化が必要であることを忘れないでください。
  • コールバックはシアン色(匿名)で表示され、最初のコールバックはDOMCONTENTLOADEDイベントからのもので、2番目は「準備完了」コールバックです。
  • 「タイマーが起動しました」(つまり、setTimeout)に気付くでしょう。したがって、それは決して瞬時ではありません。

jQueryソースコード を見ると、実際にコールバックのタイマーが設定されていることがわかります。

// Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout( jQuery.ready );

私は正確にではありませんが、それらがここで何を意味するのかわかりません(任意のアイデア)-しかし、それは動作を説明します。競合状態を回避し、UIをブロックすることは有益であることがわかりましたが、「遅延準備」は私にはわかりません。

1
Simon_Weaver