2

私のアプリケーションでは、(RequireJS から)require を使用すると、実際には load イベントと思われるイベントで domReady イベントが発生します(すべての画像、スクリプトなどの読み込みが終了したとき)。これは期待されていますか?

document.ready (jQuery から) を使用するコードがたくさんありますが、domReady イベントの発生が非常に遅いため、適切に実行されていません。私が直面している問題を示すサンプル スクリプトを作成しました。

<html>
<head>
</head>
<body>
<script type="text/javascript" src="http://ratel.apache-extras.org.codespot.com/svn-history/r6/trunk/ratel/web/js/lib/require.js"></script>
<script>
    require.config({
        paths: {
            "jquery": '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min',
            "jquery.validate": '//ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min'
        },
        shim: {
            "jquery.validate": ["jquery"]
        }
    });

    require(["jquery"], function (){
        $(document).ready(function(){
            console.log("the document is ready");
        });
    });
</script>
<img src="http://ie.microsoft.com/testdrive/HTML5/DOMContentLoaded/whidbey.jpg" width="300" height="300">
</body>
</html>

この HTML の例では、非常に大きな画像を読み込みます。$(document).ready 内のコードは、jQuery がロードされた直後に実行されると思います。ただし、代わりに、大きな画像のダウンロードが完了したときにのみ起動します。

ここで何が間違っていますか?

4

2 に答える 2

4

次のjsfiddle テストを使用すると、リスナーがwindow.DOMContentLoadedwindow.load$()およびにアタッチされrequire["domReady!]ます。

<script>
// IE patch
if (Function.prototype.bind && window.console && typeof console.log == "object") {
    ["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function (method) {
        console[method] = this.bind(console[method], console);
    }, Function.prototype.call);
}

startTime = +new Date();
require = {
    paths: {
        "domReady": "https://rawgithub.com/requirejs/domReady/2.0.1/domReady",
        "jquery": "http://code.jquery.com/jquery-1.10.2.min"
    },
    waitSeconds: 60
};
</script>
<script src="http://requirejs.org/docs/release/2.1.8/minified/require.js"></script>
<script>
function log() {
    var args = Array.prototype.slice.apply(arguments);
    var evt = args[0];
    var type = evt && evt.type;
    args = [+new Date() - startTime + "ms", type].concat(args);
    console.log.apply(console, args);
}

require(["jquery"], function($) {
    $(log("jquery.ready"));
});
require(["domReady!"], log);
window.addEventListener('load', log, false);
window.addEventListener('DOMContentLoaded', log, false);
</script>

<img id="theImg" src="http://ie.microsoft.com/testdrive/HTML5/DOMContentLoaded/whidbey.jpg" width="300" height="300">

<script>
var theImg = document.getElementById("theImg");
log("I am the trailing script and this is the image", theImg, theImg.id, theImg.parentNode, theImg.nextSibling);
</script>

これらの結果が得られます (FF 23、Chrome 29、IE 9):

FF クリーン キャッシュ。

[22:08:47.477] "488ms" undefined "I am the trailing script and this is the image" [object HTMLImageElement] "theImg" [object HTMLBodyElement] [object Text]
[22:08:47.478] "489ms" "DOMContentLoaded" [object Event]
[22:08:47.838] "849ms" undefined "jquery.ready"
[22:09:00.770] "13781ms" "load" [object Event]
[22:09:00.773] "13783ms" undefined [object HTMLDocument]

FFプライミングキャッシュ。

[22:09:19.881] "3ms" undefined "I am the trailing script and this is the image" [object HTMLImageElement] "theImg" [object HTMLBodyElement] [object Text]
[22:09:19.881] "3ms" "DOMContentLoaded" [object Event]
[22:09:19.883] "5ms" "load" [object Event]
[22:09:19.908] "30ms" undefined "jquery.ready"
[22:09:20.176] "298ms" undefined [object HTMLDocument]

クロムクリーンキャッシュ.

745ms undefined I am the trailing script and this is the image <img id=?"theImg" src=?"http:?/?/?ie.microsoft.com/?testdrive/?HTML5/?DOMContentLoaded/?whidbey.jpg" width=?"300" height=?"300">? theImg <body>?…?</body>? #text
751ms DOMContentLoaded Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: document, defaultPrevented: false…}
2024ms undefined jquery.ready fiddle.jshell.net/fiddlegrimbo/QrUxr/17/show/:53
16105ms load Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: document, defaultPrevented: false…}
16127ms undefined #document

Chrome プライミング キャッシュ。

503ms undefined I am the trailing script and this is the image <img id=?"theImg" src=?"http:?/?/?ie.microsoft.com/?testdrive/?HTML5/?DOMContentLoaded/?whidbey.jpg" width=?"300" height=?"300">? theImg <body>?…?</body>? #text
508ms DOMContentLoaded Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: document, defaultPrevented: false…}
1211ms undefined jquery.ready fiddle.jshell.net/fiddlegrimbo/QrUxr/17/show/:53
14952ms load Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: document, defaultPrevented: false…}
14953ms undefined #document

IE クリーン キャッシュ。

LOG: 363msundefinedI am the trailing script and this is the image[object HTMLImageElement]theImg[object HTMLBodyElement][object Text] 
LOG: 364msDOMContentLoaded[object Event] 
LOG: 1171msundefinedjquery.ready 
LOG: 13743msload[object Event] 
LOG: 13747msundefined[object Document] 

IE プライミング キャッシュ。

LOG: 6msundefinedI am the trailing script and this is the image[object HTMLImageElement]theImg[object HTMLBodyElement][object Text] 
LOG: 126msDOMContentLoaded[object Event] 
LOG: 128msload[object Event] 
LOG: 164msundefinedjquery.ready 
LOG: 416msundefined[object Document] 

したがって、キャッシュがクリーンな場合、コールバックの順序は FF、Chrome、および IE で同じです。

  • DOMContentLoaded
  • jquery.ready
  • window.load
  • ドムレディ!

ただし、キャッシュが準備されると、IE の順序が変わります。FFとクロームはそのまま。

また、FF と IE の両方が、2 回目ははるかに高速に実行されるようです。キャッシュがプライミングされているにもかかわらず、Chrome ではほぼ同じ遅延が発生しているようです。

これらは数回しか実行していないため、必要に応じて独自のテストを実行する必要があります。したがって、これが一貫した動作であると言っているわけではありません (そうである可能性はありますが)。

ready/load/$()/domReady! を無視します。等

</body>もちろん、これらのコールバックをすべて無視して、タグ内のページの最後にスクリプト ブロックを追加するだけでもかまいません。スクリプト ブロックの上のすべての DOM 要素は、特定の操作に使用できる必要があります。ここでも、特定のページ/サイトをテストする必要があります。

于 2013-09-09T20:55:56.900 に答える
0

https://github.com/jquery/jquery/blob/master/src/core/ready.js#L64

私は最近、自分のプロジェクトでこの問題に遭遇し、jquery が DOMContentLoaded の後、window.load の前に読み込まれるときに問題があることを発見しました。上記の jquery ソースを読むと、jquery は基本的に DOMContentLoaded が起動したことを知る方法がないため、$.ready コードが window.load を待っていることがわかります。

これは、jquery async の読み込み、ドキュメントの読み込み状態の判断 (jquery の内部)、およびドキュメント内のサイズの大きい/遅いファイルの読み込みに関する問題です。

jquery を同期的にロードするか、$.ready 機能の使用を停止するかの 2 つの選択肢があります。

于 2015-06-05T02:28:58.607 に答える