1. ホーム
  2. javascript

[解決済み] JavaScript ファイルを動的に読み込む

2022-04-30 08:56:24

質問

JavaScriptファイルを確実に、かつ動的に読み込むにはどうしたらよいでしょうか? これは、モジュールやコンポーネントを実装するために使用され、コンポーネントが「初期化」されたときに、必要なすべてのJavaScriptライブラリスクリプトを必要に応じて動的にロードすることができます。

このコンポーネントを使用するクライアントは、すべてのライブラリー・スクリプトファイルを読み込む必要がない(そして、手動で <script> タグをウェブページに追加します)。

主流のJavaScriptライブラリ(Prototype、jQueryなど)は、どのようにこれを実現しているのでしょうか? これらのツールは、複数のJavaScriptファイルを1つの再配布可能な「ビルド」バージョンのスクリプトファイルにマージしているのでしょうか? あるいは、補助的な「ライブラリ」スクリプトの動的読み込みを行っているのでしょうか?

この質問に対する補足です。 動的にインクルードされた JavaScript ファイルが読み込まれた後のイベントを処理する方法はありますか? プロトタイプには document.observe をドキュメント全体のイベントに使用します。例

document.observe("dom:loaded", function() {
  // initially hide all containers for tab content
  $$('div.tabcontent').invoke('hide');
});

script要素で利用できるイベントにはどのようなものがありますか?

どのように解決するのですか?

script 要素を動的に作成する場合は プロトタイプ :

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

ここで問題となるのは いつ 外部スクリプトファイルが完全にロードされます。

私たちはしばしば、依存するコードを次の行に書きたいことがあります。

if (iNeedSomeMore) {
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
    myFancyMethod(); // cool, no need for callbacks!
}

コールバックを使わずに、スクリプトの依存性を注入するスマートな方法があります。単にスクリプトを 同期AJAXリクエスト で、グローバルレベルでスクリプトを評価します。

Prototypeを使用する場合、Script.loadメソッドは次のようになります。

var Script = {
    _loadedScripts: [],
    include: function(script) {
        // include script only once
        if (this._loadedScripts.include(script)) {
            return false;
        }
        // request file synchronous
        var code = new Ajax.Request(script, {
            asynchronous: false,
            method: "GET",
            evalJS: false,
            evalJSON: false
        }).transport.responseText;
        // eval code on global level
        if (Prototype.Browser.IE) {
            window.execScript(code);
        } else if (Prototype.Browser.WebKit) {
            $$("head").first().insert(Object.extend(
                new Element("script", {
                    type: "text/javascript"
                }), {
                    text: code
                }
            ));
        } else {
            window.eval(code);
        }
        // remember included script
        this._loadedScripts.push(script);
    }
};