2267

を使用するスクリプトがあります$(document).readyが、jQuery 以外は使用していません。jQuery の依存関係を削除して軽量化したいと思います。

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

4

39 に答える 39

1702

IE8 ではなく、99% 以上のブラウザ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 );
}
于 2009-04-28T21:59:53.337 に答える
368

編集:

これは、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*/})
于 2011-08-13T20:52:06.120 に答える
93

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

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

于 2009-12-07T16:46:49.640 に答える
69

貧乏人の解決策:

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!");    
    };
})()

フィドルを見る

于 2012-08-04T18:13:42.553 に答える
39

私はこれを使用します:

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

注: これはおそらく新しいブラウザーでのみ機能します。特に次のブラウザーでのみ機能します

于 2013-12-23T19:14:32.707 に答える
22

本当に、 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();
        }
    }
},
于 2014-11-07T07:45:18.243 に答える
20

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

jqueryを必要としない場合があるIE8ドキュメント対応スクリプト

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();
        });
}
于 2015-02-16T14:15:41.920 に答える
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;
})();
于 2010-09-22T01:29:38.827 に答える
12

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

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

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

jsfiddle でアラートを表示する

于 2013-11-18T21:58:51.913 に答える
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 )
}
于 2012-09-05T16:56:58.027 に答える
8

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

<script>
    Your_Function();
</script>

HTML ドキュメントはトップ ボトムで解析されるためです。

于 2013-02-23T11:51:26.570 に答える
6

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");});
于 2011-09-28T11:13:41.863 に答える
4

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

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

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

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

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

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

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

于 2014-12-27T16:52:42.120 に答える
4

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);
    }
}
于 2016-02-26T18:38:27.187 に答える
3

2022年版

2022 年には、スクリプトに defer 属性を追加して、head にロードするだけです。

参照: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer

<!doctype html>
<html>
<head>
  <script src="/script.js" defer></script>
</head>
<body>

 </p>In 2022, all you need to do is put the defer attribute on your script, and load it in the head!</p>

</body>
</html>
于 2021-12-16T20:39:29.940 に答える
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();
};
于 2012-08-17T07:33:55.160 に答える
1

IE9+ の場合:

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}
于 2016-02-03T15:20:32.487 に答える
1

ここで紹介する 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 チームが実装を構築したコードです。

于 2014-08-05T11:04:29.297 に答える
0

BODY の下部近くで jQuery をロードしているが、jQuery(<func>) または jQuery(document).ready(<func>) を書き出すコードに問題がある場合は、Github でjqShimを確認してください。

独自のドキュメント対応関数を再作成するのではなく、jQuery が使用可能になるまで関数を保持し、その後 jQuery を期待どおりに処理します。jQuery を body の一番下に移動するポイントは、ページの読み込みを高速化することです。これは、テンプレートの head に jqShim.min.js をインライン化することで実現できます。

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

于 2014-02-21T17:16:59.003 に答える
-1

これは良いhttps://stackoverflow.com/a/11810957/185565貧乏人の解決策でした。1 件のコメントは、緊急時の救済策と考えられていました。これは私の修正です。

function doTheMagic(counter) {
  alert("It worked on " + counter);
}

// wait for document ready then call handler function
var checkLoad = function(counter) {
  counter++;
  if (document.readyState != "complete" && counter<1000) {
    var fn = function() { checkLoad(counter); };
    setTimeout(fn,10);
  } else doTheMagic(counter);
};
checkLoad(0);
于 2013-10-03T09:12:53.440 に答える
-2

これを試して:

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!");
});
于 2018-05-27T16:11:24.180 に答える
-3

の準備完了関数jQueryは、多くのことを行います。率直に言って、Web サイトからの出力が驚くほど小さい場合を除き、それを置き換える必要はないと思います。jQueryは非常に小さなライブラリであり、後で必要になるあらゆる種類のクロスブラウザのものを処理します。

とにかく、ここに投稿する意味はほとんどありません。開いてメソッドjQueryを見てください。bindReady

イベントモデルに応じてdocument.addEventListener("DOMContentLoaded")orのいずれかを呼び出すことから始まり、そこから続きます。document.attachEvent('onreadystatechange')

于 2009-04-28T22:02:04.343 に答える
-4

つまり、jQuery で使用される $(document).ready() の代わりに、JavaScript メソッドを使用できます。

<script>
    document.addEventListener("DOMContentLoaded", function_name, false);
    function function_name(){
        statements;
    }
</script>

したがって、ページの準備が整ったとき、つまり DOMContentLoaded のときのみ、関数 function_name() が呼び出されます。

于 2016-01-12T16:35:38.060 に答える
-7

Internet Explorer 7 以降(癖、互換性、その他の問題なし)、最新のChrome、最新のSafari、最新の Firefox 、および iframe なしをサポートする場合は、これで十分です。

is_loaded = false
callbacks = []

loaded = ->
  is_loaded = true
  for i in [0...callbacks.length]
    callbacks[i].call document
  callbacks = []

content_loaded = ->
  document.removeEventListener "DOMContentLoaded", content_loaded, true
  loaded()

state_changed = ->
  if document.readyState is "complete"
    document.detachEvent "onreadystatechange", state_changed
    loaded()

if !!document.addEventListener
  document.addEventListener "DOMContentLoaded", content_loaded, true
else
  document.attachEvent "onreadystatechange", state_changed

dom_ready = (callback) ->
  if is_loaded
    callback.call document
  else
    callbacks.push callback
于 2013-10-27T20:55:47.123 に答える