$(document).readyでjQueryなし


2017

私はを使用するスクリプトを持っています$(document).readyが、それはjQueryの他のものを使用していません。jQueryの依存関係を削除することで軽量化したいと思います。

$(document).readyjQueryを使用せずに独自の機能を実装するにはどうすればよいですか?すべての画像、フレームなどが読み込まれた後に発生window.onloadするため、使用方法は同じではないことを知っwindow.onloadています。


296
...また、間違いなく同じ機能ではありません。
Joel Mueller、

40
この回答あなたはjQueryのから望むすべてがある場合の状態、$(document).readyは、ページの最下部に代わりの上部にあなたのコードを実行することにより、簡単にその問題を解決することができます。HTML5Boilerplateはこの正確なアプローチを使用します。
Blazemonger 2013年

3
DOMContentLoadedを使用しないのはなぜですか?IE9 +です。caniuse.com/domcontentloaded developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Brock

文書の最後に電話をかけ、それで問題が解決しました。関数が呼び出されると、すべてがロードされます。
IgniteCoders 2014

回答:


1440

標準ベースの置き換えがあり、IE8ではなく98%以上のブラウザーDOMContentLoadedサポートされています

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

jQueryのネイティブ関数は、以下に示すように、単なるwindow.onloadよりもはるかに複雑です。

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            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( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

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

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

19
ここでは、実際の作業無地のJavaScript実装誰かがコードを望んでいる場合、彼らはただでドロップすることができます:stackoverflow.com/questions/9899372/...
jfriend00

4
jQuery DOM対応コードは単純化されているようです:github.com/jquery/jquery/blob/master/src/core/ready.js
Jose Nobile

2
@JoseNobileは、古いブラウザーサポートを削除したためです
huysentruitw

16
IE8から移行する準備ができていると思います...;)リンクをありがとう、@ JoseNobile。
Con Antonakos

13
後でスクリプトがロードされると、DOMContentLoadedは機能しません。jQueryドキュメントの準備は常に実行されます。
Jared Insel 2016年

343

編集:

jQuery対応の実行可能な代替品を以下に示します

function ready(callback){
    // in case the document is already rendered
    if (document.readyState!='loading') callback();
    // modern browsers
    else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback);
    // IE <= 8
    else document.attachEvent('onreadystatechange', function(){
        if (document.readyState=='complete') callback();
    });
}

ready(function(){
    // do something
});

https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/から 取得

https://stackoverflow.com/a/9899701/175071から取得した別の優れたdomReady関数


受け入れられた答えは完全とはほど遠いので、jQuery.ready()jQuery 1.6.2ソースに基づくような「準備完了」関数をつなぎ合わせました。

var ready = (function(){

    var readyList,
        DOMContentLoaded,
        class2type = {};
        class2type["[object Boolean]"] = "boolean";
        class2type["[object Number]"] = "number";
        class2type["[object String]"] = "string";
        class2type["[object Function]"] = "function";
        class2type["[object Array]"] = "array";
        class2type["[object Date]"] = "date";
        class2type["[object RegExp]"] = "regexp";
        class2type["[object Object]"] = "object";

    var ReadyObj = {
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        readyWait: 1,
        // Hold (or release) the ready event
        holdReady: function( hold ) {
            if ( hold ) {
                ReadyObj.readyWait++;
            } else {
                ReadyObj.ready( true );
            }
        },
        // Handle when the DOM is ready
        ready: function( wait ) {
            // Either a released hold or an DOMready/load event and not yet ready
            if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                if ( !document.body ) {
                    return setTimeout( ReadyObj.ready, 1 );
                }

                // Remember that the DOM is ready
                ReadyObj.isReady = true;
                // If a normal DOM Ready event fired, decrement, and wait if need be
                if ( wait !== true && --ReadyObj.readyWait > 0 ) {
                    return;
                }
                // If there are functions bound, to execute
                readyList.resolveWith( document, [ ReadyObj ] );

                // Trigger any bound ready events
                //if ( ReadyObj.fn.trigger ) {
                //    ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
                //}
            }
        },
        bindReady: function() {
            if ( readyList ) {
                return;
            }
            readyList = ReadyObj._Deferred();

            // Catch cases where $(document).ready() is called after the
            // browser event has already occurred.
            if ( document.readyState === "complete" ) {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                return setTimeout( ReadyObj.ready, 1 );
            }

            // Mozilla, Opera and webkit nightlies currently support this event
            if ( document.addEventListener ) {
                // Use the handy event callback
                document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                // A fallback to window.onload, that will always work
                window.addEventListener( "load", ReadyObj.ready, false );

            // If IE event model is used
            } else if ( document.attachEvent ) {
                // ensure firing before onload,
                // maybe late but safe also for iframes
                document.attachEvent( "onreadystatechange", DOMContentLoaded );

                // A fallback to window.onload, that will always work
                window.attachEvent( "onload", ReadyObj.ready );

                // If IE and not a frame
                // continually check to see if the document is ready
                var toplevel = false;

                try {
                    toplevel = window.frameElement == null;
                } catch(e) {}

                if ( document.documentElement.doScroll && toplevel ) {
                    doScrollCheck();
                }
            }
        },
        _Deferred: function() {
            var // callbacks list
                callbacks = [],
                // stored [ context , args ]
                fired,
                // to avoid firing when already doing so
                firing,
                // flag to know if the deferred has been cancelled
                cancelled,
                // the deferred itself
                deferred  = {

                    // done( f1, f2, ...)
                    done: function() {
                        if ( !cancelled ) {
                            var args = arguments,
                                i,
                                length,
                                elem,
                                type,
                                _fired;
                            if ( fired ) {
                                _fired = fired;
                                fired = 0;
                            }
                            for ( i = 0, length = args.length; i < length; i++ ) {
                                elem = args[ i ];
                                type = ReadyObj.type( elem );
                                if ( type === "array" ) {
                                    deferred.done.apply( deferred, elem );
                                } else if ( type === "function" ) {
                                    callbacks.push( elem );
                                }
                            }
                            if ( _fired ) {
                                deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
                            }
                        }
                        return this;
                    },

                    // resolve with given context and args
                    resolveWith: function( context, args ) {
                        if ( !cancelled && !fired && !firing ) {
                            // make sure args are available (#8421)
                            args = args || [];
                            firing = 1;
                            try {
                                while( callbacks[ 0 ] ) {
                                    callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
                                }
                            }
                            finally {
                                fired = [ context, args ];
                                firing = 0;
                            }
                        }
                        return this;
                    },

                    // resolve with this as context and given arguments
                    resolve: function() {
                        deferred.resolveWith( this, arguments );
                        return this;
                    },

                    // Has this deferred been resolved?
                    isResolved: function() {
                        return !!( firing || fired );
                    },

                    // Cancel
                    cancel: function() {
                        cancelled = 1;
                        callbacks = [];
                        return this;
                    }
                };

            return deferred;
        },
        type: function( obj ) {
            return obj == null ?
                String( obj ) :
                class2type[ Object.prototype.toString.call(obj) ] || "object";
        }
    }
    // The DOM ready check for Internet Explorer
    function doScrollCheck() {
        if ( ReadyObj.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
        ReadyObj.ready();
    }
    // Cleanup functions for the document ready method
    if ( document.addEventListener ) {
        DOMContentLoaded = function() {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            ReadyObj.ready();
        };

    } else if ( document.attachEvent ) {
        DOMContentLoaded = function() {
            // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", DOMContentLoaded );
                ReadyObj.ready();
            }
        };
    }
    function ready( fn ) {
        // Attach the listeners
        ReadyObj.bindReady();

        var type = ReadyObj.type( fn );

        // Add the callback
        readyList.done( fn );//readyList is result of _Deferred()
    }
    return ready;
})();

使い方:

<script>
    ready(function(){
        alert('It works!');
    });
    ready(function(){
        alert('Also works!');
    });
</script>

このコードがどの程度機能的であるかはわかりませんが、表面的なテストでは問題なく機能しました。これにはかなり時間がかかったので、あなたや他の人が恩恵を受けられることを願っています。

PS .:私はそれをコンパイルすることをお勧めます。

または、http : //dustindiaz.com/smallest-domready-everを使用できます。

function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()}
r(function(){/*code to run*/});

または、新しいブラウザのみをサポートする必要がある場合はネイティブ関数(jQueryの準備とは異なり、ページが読み込まれた後にこれを追加すると実行されません)

document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})

14
@TimoHuovinenの代替:Zepto.js(9.1 kb)、Snack.js(8.1 kb)、$ dom(2.3 kb)、および140 Medley(0.5 kb)。編集: Enderもご覧ください。
Frederik Krautwald、2014年

2
@FrederikKrautwald $ domは私が望んでいるように聞こえますが、それが目的に合うかどうかはわかりません。Zeptoも本当に有望に見えます、共有してくれてありがとう!
Timo Huovinen、2014年

@TimoHuovinen Enderをまだ見ていない場合は、ぜひenderjs.comをご覧ください
Frederik Krautwald、2014年

2
@Timo Huovinen:あなたの質問は本当に、本当に広いです!jQueryが作成されたとき、ブラウザーによって生成されたクロスブラウザーの問題の多くに適合しましたが、現在はそれほど重要ではありません。今日、「JavaScriptのみ」は以前よりも簡単です。現時点では、「すべてを含む大きな20kb圧縮」を作成することは、私がそれらすべてをリストしたくない多くの理由から、確かに良い考えでした。
dotpush 14

1
私はこれが好きではありません。人々がこの答えを好むなら、なぜ最初にjQueryをドロップしたいのかを自問してください。すべてのブラウザーのフォールバックがバンドルに戻ってまったく同じ機能を抽出するのであれば、それは少し無意味です。そもそもjQueryを回避するという意味ではないでしょうか。
Phil

208

3つのオプション:

  1. もし scriptが本文の最後のタグの、スクリプトタグが実行される前にDOMが準備されます。
  2. DOMの準備ができると、「readyState」が「complete」に変わります
  3. すべてを「DOMContentLoaded」イベントリスナーの下に置きます

onreadystatechange

  document.onreadystatechange = function () {
     if (document.readyState == "complete") {
     // document is ready. Do your stuff here
   }
 }

出典:MDN

DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
   console.log('document is ready. I can sleep now');
});

石器時代のブラウザーが心配: jQueryソースコードに移動してready関数を使用します。その場合、ライブラリ全体を解析して実行するのではなく、ごく一部を実行します。


3
この2番目の例は、マークされた回答よりもはるかにエレガントで簡潔です。これが正しいものとしてマークされなかったのはなぜですか?
0112 2014

2
それでもDOMContentLoadedの+1は、まさに私が望んでいたことを行いました。
tripleee 2014

1
onreadystatechangeは私のためのトリックを行いました...非同期jqueryの読み込み後にスクリプトを実行する必要がありました。
Abram

2
参考までに、#1は完全に真実ではありません。DOMが完了する前に、ページの最後にあるスクリプトが読み込まれる可能性があります。そのため、リスナーは優れています。彼らはブラウザが終了したときにリッスンします。最後に置くと、ブラウザのレンダリングよりもスクリプトの読み込みが遅かったことがわかります。
Machavity 2016年

1
このバリアントは、ドキュメントの読み込みが既に完了している場合にも機能します。可能な場合は、(imo best)回答を更新してください:if(document.readyState == 'complete'){init(); } else {document.onreadystatechange = function(){if(document.readyState == 'complete'){init(); }}}
ZPiDER 2017年

87

<script>/*JavaScript code*/</script>右を終了 </body>タグの前に置きます。

確かに、JavaScriptファイルa la document.readyで何かを行うだけでなく、HTMLファイルを変更する必要があるため、これはすべての人の目的に合わない可能性がありますが、それでも...


互換性の問題があったようです。たとえば、ページの準備がまだできていないため、これらのブラウザーやこれらのブラウザーではこれを実行できません。残念ながら、もっとはっきり覚えることはできません。それにもかかわらず、すべてのケースの99%で十分に近い方法のために+1(そしてYahoo!によって提案されました)。
Boldewyn、2009

7
実際、ページの下部にスクリプト要素を配置することは、ほぼ完璧なソリューションです。クロスブラウザで動作し、document.readyを完全にシミュレートします。唯一の欠点は、スマートコードを使用するよりも(少し)邪魔になることです。準備中の関数またはinit関数を呼び出すには、作成するスクリプトのユーザーに追加のスクリプトフラグメントを追加するよう依頼する必要があります。
Stijn de Witt

@StijndeWitt-init関数を呼び出さなければならないというのはどういう意味ですか?document.readyを使用するスクリプトは、それを呼び出すために他のクライアントコードを必要とせず、自己完結型であり、コードが本文の最後に含まれているものと同等のものも自己完結型であり、それを呼び出すには他のコードが必要です。
nnnnnn 2017年

1
スクリプト bodyの終了タグの、終了タグの前に配置しないのはなぜ</html>ですか。
Charles Holbrow

1
@CharlesHolbrowすべてのブラウザで正しく解釈されますが、有効なhtmlにしたい場合は、htmlタグに含まれるのはheadおよびのみbodyです。
Alvaro Montoro 2018

66

貧乏人の解決策:

var checkLoad = function() {   
    document.readyState !== "complete" ? setTimeout(checkLoad, 11) : alert("loaded!");   
};  

checkLoad();  

フィドルを見る

これを追加しました、少し良いと思います、自分のスコープ、そして非再帰的

(function(){
    var tId = setInterval(function() {
        if (document.readyState == "complete") onComplete()
    }, 11);
    function onComplete(){
        clearInterval(tId);    
        alert("loaded!");    
    };
})()

フィドルを見る


8
@PhilipLangfordまたは、それをaの中に入れてsetInterval、再帰を完全に削除します。
Alex W

1
@Raveren、うーん、その通りです。投稿したときにテストしたと確信しています。とにかく、さらにシンプルになっただけで、関数は呼び出されるだけで、ラッピングはありません。
Jakob Sternberg、

24
これはセクシーではありません。いいえ、申し訳ありません。タイマー/インターバルを使用してものを検出することは「うまくいく」かもしれませんが、このようにプログラミングを続けると、その価値のあるより大きなプロジェクトは急降下します。このようにハッキングしないでください。ちゃんとして。お願いします。この種のコードは、より良いソリューションがあり、それを知っているため、開発エコシステムに害を与えます。
dudewad 14

1
私はこの答えはdustindiaz.com/smallest-domready-everにはるかに近いと思うので、スクリプトを改善しました:jsfiddle.net/iegik/PT7x9
iegik 14

1
@ReidBlomquistはい、そしてこれは「間違った」方法であり、それが私が指摘していることです(多少断固としてですが、私は知っています)。あなたはそれを間違って行うことでエコシステムをどうにかして「助けている」と言うことができます、しかし問題は人々がより良いことを知る経験がないので人々が「良い」コードのために取る悪いコードの量があるということです彼らはその悪いコードを取り、実際の本番アーキテクチャソリューションに実装するため、エコシステムを支援しません。したがって、私はこの「間違い」について意見を異ならせなければならないでしょう。
dudewad 14

34

私はこれを使います:

document.addEventListener("DOMContentLoaded", function(event) { 
    //Do work
});

注:これはおそらく新しいブラウザー、特に次のブラウザーでのみ機能します:http : //caniuse.com/#feat=domcontentloaded


13
実際にIE9以上
パスカリウス14年

document_startまたはdocument_idleイベントをフックする場合、これはChrome拡張機能のコンテンツスクリプトでもうまく機能します。
Volomike、

21

実際、Internet Explorer 9以降のみに関心がある場合は、次のコードで置き換えることができますjQuery.ready

    document.addEventListener("DOMContentLoaded", callback);

Internet Explorer 6といくつかの非常に奇妙で珍しいブラウザーについて心配する場合、これは動作します:

domReady: function (callback) {
    // Mozilla, Opera and WebKit
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", callback, false);
        // If Internet Explorer, the event model is used
    } else if (document.attachEvent) {
        document.attachEvent("onreadystatechange", function() {
            if (document.readyState === "complete" ) {
                callback();
            }
        });
        // A fallback to window.onload, that will always work
    } else {
        var oldOnload = window.onload;
        window.onload = function () {
            oldOnload && oldOnload();
            callback();
        }
    }
},

18

この質問はかなり前に尋ねられました。この質問を見ただけの人のために、「jqueryは必要ないかもしれません」というサイトがあります。 、IEサポートのレベルごとに、jqueryのすべての機能が機能し、いくつかの小さなライブラリが提供されます。

あなたによるIE8ドキュメントレディスクリプトはjqueryを必要としないかもしれません

function ready(fn) {
    if (document.readyState != 'loading')
        fn();
    else if (document.addEventListener)
        document.addEventListener('DOMContentLoaded', fn);
    else
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading')
                fn();
        });
}

なぜそれ'onreadystatechange'が必要なのかというと、なぜでしょうかdocument.attachEvent('onload', fn);
ルーク

13

私は最近、これをモバイルサイトに使用していました。これは、 "Pro JavaScript Techniques"のJohn Resigの簡易バージョンです。addEventに依存します。

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load", isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();

13
このコードには注意してください。$(document).readyと同等ではありません。このコードは、DOMが完全にロードされていることを保証しないdocument.bodyの準備ができたときにコールバックをトリガーします。
Karolis

12

クロスブラウザ(古いブラウザも)と簡単な解決策:

var docLoaded = setInterval(function () {
    if(document.readyState !== "complete") return;
    clearInterval(docLoaded);

    /*
        Your code goes here i.e. init()
    */
}, 30);

jsfiddleにアラートを表示


DOMの読み込みに30ms以上かかる場合を除いて、コードは実行されません。
Quelklef 2017

1
setIntervalではなくsetIntervalである@Quelklef
Pawel

11

jQueryの回答は私にとってかなり役に立ちました。少しのリファクタリングで、それは私のニーズにうまく適合しました。それが他の人の役に立つことを願っています。

function onReady ( callback ){
    var addListener = document.addEventListener || document.attachEvent,
        removeListener =  document.removeEventListener || document.detachEvent
        eventName = document.addEventListener ? "DOMContentLoaded" : "onreadystatechange"

    addListener.call(document, eventName, function(){
        removeListener( eventName, arguments.callee, false )
        callback()
    }, false )
}

一部のブラウザではremoveListener、ドキュメントをコンテキストとして呼び出す必要があります。removeListener.call(document, ...
Ron

9

これは、すべてのブラウザー(IE 8を含む)で機能するDOMをテストするための最小のコードスニペットです。

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

この回答を参照してください。


6

これをHTMLページの下部に追加するだけです...

<script>
    Your_Function();
</script>

というのも、HTML文書はトップボトムで解析されるからです。


7
このコードが実行されたときにDOMが構築されたことをどのようにして知っていますか?ロードおよび解析されたCSSを含みますか?ブラウザAPI DOMContentLoadedはそのために設計されています。
Dan

それは本当に彼がjsで何をしたいかに依存します。ページが終了したかどうかにかかわらず、実際に何かを実行する必要がある場合。
davefrassoni

5

Rock Solid addEvent()およびhttp://www.braksator.com/how-to-make-your-own-jqueryを参照する価値があります

サイトがダウンした場合のコードは次のとおりです

function addEvent(obj, type, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
        EventCache.add(obj, type, fn);
    }
    else {
        obj["on"+type] = obj["e"+type+fn];
    }
}

var EventCache = function(){
    var listEvents = [];
    return {
        listEvents : listEvents,
        add : function(node, sEventName, fHandler){
            listEvents.push(arguments);
        },
        flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
            };
        }
    };
}();

// Usage
addEvent(window, 'unload', EventCache.flush);
addEvent(window, 'load', function(){alert("I'm ready");});

2番目のリンクは壊れています。
Peter Mortensen


4

このクロスブラウザコードは、DOMの準備ができると関数を呼び出します。

var domReady=function(func){
    var scriptText='('+func+')();';
    var scriptElement=document.createElement('script');
    scriptElement.innerText=scriptText;
    document.body.appendChild(scriptElement);
};

仕組みは次のとおりです。

  1. の最初の行は、関数domReadytoStringメソッドを呼び出して、渡された関数の文字列表現を取得し、関数をすぐに呼び出す式にラップします。
  2. 残りはdomReady、式を使用してスクリプト要素を作成し、それをbodyドキュメントのにます。
  3. ブラウザはbody、DOMの準備ができた後に追加されたスクリプトタグを実行します。

たとえば、これを行うdomReady(function(){alert();});と、次のようにbody要素に追加されます。

 <script>(function (){alert();})();</script>

これは、ユーザー定義関数に対してのみ機能することに注意してください。以下は機能しません:domReady(alert);



3

このソリューションはどうですか?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};

3
「load」を使用して、ウィンドウでaddEventListenerを使用できます。リスナーは1つずつ実行され、手動でチェーンする必要はありません。
Zaffy

1
しかし、負荷は作動可能とは異なります。「ロード」は、ドキュメントが「準備完了」になる前でも発生します。準備ができたドキュメントにはDOMが読み込まれています。読み込まれたウィンドウは必ずしもDOMを準備している必要はありません。しかし良い答え
用Mzn

1
@Mzn:それは逆だと思います。ドキュメントの準備はウィンドウロードイベントのに発生すると思います。「一般的に、すべての画像が完全に読み込まれるのを待つ必要はありません。コードをより早く実行できる場合は、通常、それを.ready()メソッドに送信されるハンドラーに配置するのが最善です。」(api.jquery.com/load-event
タイラーリック

これにより、ページ上の残りのwindow.onloadイベントがオーバーライドされ、問題が発生します。既存のイベントの上にイベントを追加する必要があります。
Teoman Shipahi 2014

読み込みイベントは遅すぎる可能性があります。サードパーティの外部のjs / imagesに依存している場合、これを使用するのは面倒です...制御していない無応答のサーバーであり、すべてが失敗します。DOMContentLoadedの使用は最適化だけでなく、安全でもあります。
dotpush 14

3

jQueryと比較して、JavaScript同等のものを使用することは常に良いことです。1つの理由は、依存するライブラリが1つ少ないことであり、jQueryの同等のライブラリよりもはるかに高速です。

jQueryの同等の素晴らしいリファレンスの1つは、http://youmightnotneedjquery.com/です。です。

あなたの質問に関する限り、私は上記のリンクから以下のコードを取得しました:)警告のみがInternet Explorer 9以降でのみ機能することです。

function ready(fn) {
    if (document.readyState != 'loading') {
        fn();
    }
    else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

3

ほとんど最小限で100%機能

私はPlainJSから回答を選びましたが、それは私にとってはうまくいきます。DOMContentLoadedすべてのブラウザで受け入れられるように拡張されています。


この関数は、jQueryの$(document).ready()メソッドと同等です。

document.addEventListener('DOMContentLoaded', function(){
    // do something
});

ただし、jQueryとは対照的に、このコードは最新のブラウザー(IE> 8)でのみ正しく実行され、このスクリプトが挿入されたときに(Ajaxなどを介して)文書が既にレンダリングされている場合は機能しません。したがって、これを少し拡張する必要があります。

function run() {
    // do something
}

// in case the document is already rendered
if (document.readyState!='loading') run();
// modern browsers
else if (document.addEventListener) 
document.addEventListener('DOMContentLoaded', run);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
    if (document.readyState=='complete') run();
});

これは基本的にすべての可能性をカバーし、jQueryヘルパーの実行可能な置き換えです。


2

最小限の実装でほとんどの単純なケースのトリックを実行する可能性がある、私たちのクロスブラウザ実装の迅速で汚いものが見つかりました:

window.onReady = function onReady(fn){
    document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};

なにdoc.body
Nabi KAZ 2016年

2

ここで紹介するsetTimeout / setIntervalソリューションは、特定の状況でのみ機能します。

この問題は、特に8までの古いInternet Explorerバージョンで発生します。

これらのsetTimeout / setIntervalソリューションの成功に影響を与える変数は次のとおりです。

1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding

この特定の問題を解決する元の(ネイティブJavaScript)コードは次のとおりです。

https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)

これは、jQueryチームが実装を構築した元のコードです。


1

これが私が使用するもので、高速で、私が考えるすべてのベースをカバーしています。IE <9を除くすべてで機能します。

(() => { function fn() {
    // "On document ready" commands:
    console.log(document.readyState);
};  
  if (document.readyState != 'loading') {fn()}
  else {document.addEventListener('DOMContentLoaded', fn)}
})();

これはすべてのケースをキャッチするようです:

  • DOMの準備ができている場合(DOMが「読み込み中」ではなく、「インタラクティブ」または「完全」の場合)に即座に起動します。
  • DOMがまだロードされている場合は、DOMが利用可能になったとき(インタラクティブ)にイベントリスナーを設定します。

DOMContentLoadedイベントはIE9やその他すべてで利用できるので、個人的にはこれを使用しても問題ないと思います。ES2015からES5にコードを変換しない場合は、arrow関数宣言を通常の無名関数に書き換えます。

すべてのアセットが読み込まれ、すべての画像が表示されるまで待機する場合は、代わりにwindow.onloadを使用します。


1

非常に古いブラウザをサポートする必要がない場合は、外部スクリプトがasync属性でロードされている場合でも、次の方法でサポートできます。

HTMLDocument.prototype.ready = new Promise(function(resolve) {
   if(document.readyState != "loading")
      resolve();
   else
      document.addEventListener("DOMContentLoaded", function() {
         resolve();
      });
});

document.ready.then(function() {
   console.log("document.ready");
});


0

BODYの下部近くにあるjQueryをロードしているが、jQuery(<func>)またはjQuery(document).ready(<func>)を書き込むコードに問題がある場合は、GithubのjqShimをチェックしてください。

独自のドキュメント対応関数を再作成するのではなく、jQueryが利用可能になるまで関数を保持し、期待どおりにjQueryを続行します。jQueryを本文の下部に移動する目的は、ページの読み込みを高速化することですが、テンプレートの先頭にあるjqShim.min.jsをインライン化することで、それを実現できます。

結局、WordPressのすべてのスクリプトをフッターに移動するためにこのコードを記述し、このシムコードだけがヘッダーに直接配置されるようになりました。


0

これを試して:

function ready(callback){
    if(typeof callback === "function"){
        document.addEventListener("DOMContentLoaded", callback);
        window.addEventListener("load", callback);
    }else{
        throw new Error("Sorry, I can not run this!");
    }
}
ready(function(){
    console.log("It worked!");
});

笑コールバックを2回実行します
Andrew

0
function onDocReady(fn){ 
    $d.readyState!=="loading" ? fn():document.addEventListener('DOMContentLoaded',fn);
}

function onWinLoad(fn){
    $d.readyState==="complete") ? fn(): window.addEventListener('load',fn);
} 

onDocReadyは、HTML domが完全にアクセス/解析/操作する準備ができたときにコールバックを提供します。

onWinLoadは、すべてがロードされたときにコールバックを提供します(画像など)

  • これらの関数はいつでも呼び出すことができます。
  • 複数の「リスナー」をサポートします。
  • どのブラウザでも動作します。

0
(function(f){
  if(document.readyState != "loading") f();
  else document.addEventListener("DOMContentLoaded", f);
})(function(){
  console.log("The Document is ready");
});

これは他の答えがしないことを何に追加しますか?
dwjohnston

自己完結型のクロージャーを使用し(グローバルな「ウィンドウ」スコープにはデータを入力しません)、すべてのブラウザーで機能し、非常にコンパクトです。私はそれのような他の答えを見ません。
ダスティンポワッサン2018年

また、DOMが(jQuery.readyのように)既にロードされた後でも機能しますが、これらの回答のほとんどは失敗します。
ダスティンポワッサン2018年

0

ほとんどのバニラJS Ready関数は 、ドキュメントが既に読み込まDOMContentLoadedれた後にハンドラーが設定されるシナリオを考慮しません。つまり、関数は実行されません。これはDOMContentLoadedasync外部スクリプト(<script async src="file.js"></script>)。

チェックし、以下のコードDOMContentLoadedのドキュメントだ場合にだけはreadyStateなっていませんinteractivecomplete

var DOMReady = function(callback) {
  document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback());
};
DOMReady(function() {
  //DOM ready!
});

IEもサポートしたい場合:

var DOMReady = function(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback());
    } else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading') {
                callback();
            }
        });
    }
};

DOMReady(function() {
  // DOM ready!
});

0

私は単に使用します:

setTimeout(function(){
    //reference/manipulate DOM here
});

そして、document.addEventListener("DOMContentLoaded" //etc一番上の回答とは異なり、IE9までさかのぼって動作します -http ://caniuse.com/#search=DOMContentLoaded唯一のように、最近、IE11のように示します。

興味深いことにsetTimeout、2009年にこの解決策を見つけました。DOMの準備ができているかどうかをチェックしていますか。「DOMの準備状況を確認するために、さまざまなフレームワークのより複雑なアプローチを使用するのはやり過ぎだ」という意味で、おそらく少し上手く表現されているかもしれません。

この手法が機能する理由についての私の最高の説明は、そのようなsetTimeoutを含むスクリプトに到達すると、DOMが解析されているため、setTimeout内のコードの実行はその操作が完了するまで遅延されるということです。

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