13

ばかげた質問をする危険を冒して、私はそれを試してみます。

RequireJsが依存関係をロードしているときに進行状況インジケーターを表示することは可能ですか?

例えば:

require(['jquery'], function($) {

    // Well, jQuery loaded in quite some time due to a low-speed connection
    //
    // Or maybe I wanted to show an overlay to prevent user of clicking on UI widgets until the load is complete
});

Google検索に表示されなかったプラグインがある場合は、RequireJSソースの変更を開始したくありません。

ご協力ありがとうございます。

4

3 に答える 3

13

スピナーまたは進行状況インジケーターを表示することはできますが、バー自体を表示することはできません。requirejsのステータス(現在ロード中またはアイドル中)を取得できましたが、モジュールのロードごとに依存関係が解析されるため、ロード済み/ロードする必要のあるモジュールの割合は取得できませんでしたが、最初は取得できませんでした。

しかし、とにかく、ユーザーが待っている間、少なくとも単純なスピナーを備えたページは、単なる空白のページよりもはるかに優れています。

requirejsへの変更は必要ありません!それで..

次のファイルrequire.conf.jsがあると仮定します

require.config({...})
require(["app"], function () { 

// main entry point to your hugde app's code 
});

そしてそれはを使用してhtmlによってロードされます

<script data-main="require.conf" type="text/javascript" src="bower_components/requirejs/require.js"></script>

これは標準のrequirejsシナリオです。インジケーターをに追加しましょう

<div id="requirejs-loading-panel">
    <div id="requirejs-loading-status"></div>
    <div id="requirejs-loading-module-name"></div>
</div>

では、require.onResourceLoadというrequirejsの関数に追いつき、必要なすべての魔法を実行しましょう。これは、モジュールがロードされるたびにrequirejsによって呼び出され、requirejsのコンテキストをdepツリーおよび他のすべてのスタッフに渡します。requirejsが何かをロードしているかどうかを調べるために、コンテキストを使用します。onResourceLoad()はロード中にのみ呼び出され、ロードが完了したときではないため、スケジュールされたタイマー呼び出しで実行しました。このコードはrequire.js.confに追加する必要があります:

require.onResourceLoad = function (context, map, depMaps) {


    var loadingStatusEl = document.getElementById('requirejs-loading-status'),
        loadingModuleNameEl = document.getElementById('requirejs-loading-module-name');
    var panel = document.getElementById('requirejs-loading-panel');

    if (loadingStatusEl && loadingModuleNameEl) {


        if (!context) { // we well call onResourceLoad(false) by ourselves when requirejs is not loading anything => hide the indicator and exit

            panel.style.display = "none";
            return;
        }

        panel.style.display = ""; // show indicator when any module is loaded and shedule requirejs status (loading/idle) check
        clearTimeout(panel.ttimer); 
        panel.ttimer = setTimeout(function () {


            var context = require.s.contexts._;
            var inited = true;
            for (name in context.registry) {
                var m = context.registry[name];

                if (m.inited !== true) {
                    inited = false;
                    break;
                }

            } // here the "inited" variable will be true, if requirejs is "idle", false if "loading"

            if (inited) {
                require.onResourceLoad(false);  // will fire if module loads in 400ms. TODO: reset this timer for slow module loading
            }

        }, 400)
        if (map && map.name) { // we will add one dot ('.') and a currently loaded module name to the indicator

            loadingStatusEl.innerHTML = loadingStatusEl.innerHTML += '.'; //add one more dot character
            loadingModuleNameEl.innerHTML = map.name + (map.url ? ' at ' + map.url : '');
        }
    } else {


    }


};

1つの問題は、ロードに必要なモジュールの量をどういうわけか把握できないため、ロードの進行状況の実際の割合を計算できないことです。しかし、少なくとも、何かをロードしているかどうか(そしてイベントは現在モジュール名をロードしている)を見つけて、神経質なユーザーに見せることはできます

于 2014-04-07T08:22:48.877 に答える
10

v。2.1.19以降、RequireJSにはonNodeCreatedconfigプロパティがあります。<script>関数を割り当てると、モジュールをロードするために要素がドキュメントに追加されるたびに、その関数が呼び出されます。

関数には、、、、および引数が提供さnodeれます。にイベントリスナーをアタッチすることで、スクリプトがロードされたか、ロードに失敗したかを検出できます。configmoduleNameurlnode

これで、読み込みプロセスの開始と停止を検出し、その情報を使用してユーザーに通知できます。

require.config({
  /* ... paths, shims, etc. */
  onNodeCreated: function(node, config, moduleName, url) {
    console.log('module ' + moduleName + ' is about to be loaded');

    node.addEventListener('load', function() {
      console.log('module ' + moduleName + ' has been loaded');
    });

    node.addEventListener('error', function() {
      console.log('module ' + moduleName + ' could not be loaded');
    });
  },
});

IE <9の場合、イベントリスナーをアタッチするための追加のコードが必要になります。

注:これは、RequireJSによって直接要求されたモジュールに対してのみ機能します。プラグイン(requirejs / textなど)はそれぞれ独自のロードメカニズムを使用し、トリガーしませんonNodeCreated。いくつかのトリガーonXhronXhrCompleteはいえ、あなたもそれらを処理することができます:

require.config({
  /* ... paths, shims, etc. */
  config: {
    text: {
      onXhr: function(xhr, url) {
        console.log('file ' + url + ' is about to be loaded');
      },
      onXhrComplete: function(xhr, url) {
        console.log('file ' + url + ' has been loaded');
      }
    }
  }
});
于 2016-01-04T16:15:30.417 に答える
8

いいえ、これは不可能です。RequrieJsは、DOMに新しいスクリプトタグを作成してモジュールをロードし、ロードイベントをリッスンします。ロードの開始と終了の間に更新イベントはありません。したがって、これはrequireJsの制限ではなく、DOMの制限です。

于 2013-03-24T15:45:14.993 に答える