質問

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

コンポーネントを使用するクライアントは、すべてのライブラリ スクリプト ファイルをロードする (および手動で挿入する) 必要はありません。 <script> タグを Web ページに追加します)。このコンポーネントは、「メイン」コンポーネントのスクリプト ファイルのみを実装します。

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

この質問への追加: 動的に組み込まれた JavaScript ファイルがロードされた後にイベントを処理する方法はありますか? プロトタイプには document.observe ドキュメント全体のイベントの場合。例:

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

スクリプト要素で使用できるイベントは何ですか?

役に立ちましたか?

解決

動的スクリプト タグを記述することもできます (次を使用します)。 プロトタイプ):

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);
    }
};

他のヒント

JavaScript には import / include / require はありませんが、目的を達成するには主に 2 つの方法があります。

1 - AJAX 呼び出しでロードしてから eval を使用できます。

これは最も簡単な方法ですが、JavaScript の安全設定によりドメインに制限され、eval を使用するとバグやハッキングへの扉が開かれてしまいます。

2 - HTML にスクリプト URL を含むスクリプト タグを追加します。

間違いなく最善の方法です。外部サーバーからでもスクリプトを読み込むことができ、ブラウザーのパーサーを使用してコードを評価するのでクリーンです。タグは Web ページの先頭または本文の下部に配置できます。

ここでは、これらの解決策の両方について説明し、説明します。

さて、あなたが知っておくべき大きな問題があります。これを行うと、コードをリモートでロードすることになります。最近の Web ブラウザは、パフォーマンスを向上させるためにすべてを非同期的に読み込むため、ファイルを読み込んで現在のスクリプトを実行し続けます。

つまり、これらのトリックを直接使用すると、ロードを要求した次の行では、新しくロードされたコードはまだロード中であるため、使用できなくなります。

例:my_lovely_script.js には MySuperObject が含まれています

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

次に、F5 キーを押してページをリロードします。そしてそれはうまくいきます!紛らわしい...

それで、それについて何をすればよいでしょうか?

さて、あなたは私があなたに与えたリンクで著者が提案するハックを使用することができます。要約すると、急いでいる人のために、スクリプトのロード時に en イベントを使用してコールバック関数を実行します。したがって、リモート ライブラリを使用するすべてのコードをコールバック関数に含めることができます。例:

function loadScript(url, callback)
{
    // adding the script tag to the head as suggested before
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = url;

   // then bind the event to the callback function 
   // there are several events for cross browser compatibility
   script.onreadystatechange = callback;
   script.onload = callback;

   // fire the loading
   head.appendChild(script);
}

次に、スクリプトがラムダ関数にロードされた後に、使用するコードを記述します。

var myPrettyCode = function() {
    // here, do what ever you want
};

次に、以下をすべて実行します。

loadScript("my_lovely_script.js", myPrettyCode);

はい、分かりました。しかし、これだけのことを書くのは面倒です。

その場合は、いつものように素晴らしい無料の jQuery フレームワークを使用できます。これを使用すると、まったく同じことを 1 行で実行できます。

$.getScript("my_lovely_script.js", function() {
    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script
});

私が使用したのは、 最近ははるかに複雑ではないバージョンjQuery:

<script src="scripts/jquery.js"></script>
<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  var $head = $("head");
  for (var i = 0; i < js.length; i++) {
    $head.append("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>

私がテストしたすべてのブラウザでうまく動作しました。IE6/7、Firefox、Safari、Opera。

アップデート: jQuery なしのバージョン:

<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  for (var i = 0, l = js.length; i < l; i++) {
    document.getElementsByTagName("head")[0].innerHTML += ("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>

基本的にはあなたが Adam にしたのと同じことをしましたが、作業を完了するために head タグに確実に追加するように少し変更しました。スクリプトと CSS ファイルの両方を処理するための include 関数 (以下のコード) を作成しただけです。

この関数は、スクリプトまたは CSS ファイルがまだ動的にロードされていないことも確認します。手動でコード化された値はチェックされないため、もっと良い方法があったかもしれませんが、目的は果たしました。

function include( url, type ){
    // First make sure it hasn't been loaded by something else.
    if( Array.contains( includedFile, url ) )
        return;

    // Determine the MIME-type
    var jsExpr = new RegExp( "js$", "i" );
    var cssExpr = new RegExp( "css$", "i" );
    if( type == null )
        if( jsExpr.test( url ) )
            type = 'text/javascript';
        else if( cssExpr.test( url ) )
            type = 'text/css';

    // Create the appropriate element.
    var tag = null;
    switch( type ){
        case 'text/javascript' :
            tag = document.createElement( 'script' );
            tag.type = type;
            tag.src = url;
            break;
        case 'text/css' :
            tag = document.createElement( 'link' );
            tag.rel = 'stylesheet';
            tag.type = type;
            tag.href = url;
            break;
    }

    // Insert it to the <head> and the array to ensure it is not
    // loaded again.
    document.getElementsByTagName("head")[0].appendChild( tag );
    Array.add( includedFile, url );
}

もう一つの素晴らしい答え

$.getScript("my_lovely_script.js", function(){


   alert("Script loaded and executed.");
  // here you can use anything you defined in the loaded script

 });

https://stackoverflow.com/a/950146/671046

これが私が見つけたコードの例です...誰かがより良い方法を持っていますか?

  function include(url)
  {
    var s = document.createElement("script");
    s.setAttribute("type", "text/javascript");
    s.setAttribute("src", url);
    var nodes = document.getElementsByTagName("*");
    var node = nodes[nodes.length -1].parentNode;
    node.appendChild(s);
  }

jQuery がすでにロードされている場合は、次を使用する必要があります。 $.getScript.

これには、コールバック関数が組み込まれており(依存コードが実行される前にスクリプトがロードされることを保証するため)、キャッシュを制御できるという点で、ここでの他の回答よりも利点があります。

誰かがより良い方法を持っていますか?

スクリプトを本文に追加するだけで、ページの最後のノードに追加するよりも簡単だと思います。これはどう:

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}

ネットで見つけたさらに別の解決策を使用しました...これはクリエイティブコモンズの下にあります 関数を呼び出す前にソースが含まれているかどうかを確認します ...

ファイルはここで見つけることができます: include.js

/** include - including .js files from JS - bfults@gmail.com - 2005-02-09
 ** Code licensed under Creative Commons Attribution-ShareAlike License 
 ** http://creativecommons.org/licenses/by-sa/2.0/
 **/              
var hIncludes = null;
function include(sURI)
{   
  if (document.getElementsByTagName)
  {   
    if (!hIncludes)
    {
      hIncludes = {}; 
      var cScripts = document.getElementsByTagName("script");
      for (var i=0,len=cScripts.length; i < len; i++)
        if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
    }
    if (!hIncludes[sURI])
    {
      var oNew = document.createElement("script");
      oNew.type = "text/javascript";
      oNew.src = sURI;
      hIncludes[sURI]=true;
      document.getElementsByTagName("head")[0].appendChild(oNew);
    }
  }   
} 

に素晴らしい機能があることを知りました ゆい3 (この記事の執筆時点ではプレビュー リリースで利用可能です)。あまりコードを書かなくても、YUI ライブラリや「外部」モジュール (探しているもの) に依存関係を簡単に挿入できます。 YUIローダー.

また、外部モジュールがロードされるとすぐに呼び出される関数に関する 2 番目の質問にも答えます。

例:

YUI({
    modules: {
        'simple': {
            fullpath: "http://example.com/public/js/simple.js"
        },
        'complicated': {
            fullpath: "http://example.com/public/js/complicated.js"
            requires: ['simple']  // <-- dependency to 'simple' module
        }
    },
    timeout: 10000
}).use('complicated', function(Y, result) {
    // called as soon as 'complicated' is loaded
    if (!result.success) {
        // loading failed, or timeout
        handleError(result.msg);
    } else {
        // call a function that needs 'complicated'
        doSomethingComplicated(...);
    }
});

私にとっては完璧に機能し、依存関係を管理できるという利点があります。詳細については、YUI ドキュメントを参照してください。 YUI 2 カレンダーの例.

ご希望の場合は、 同期 スクリプトを読み込む場合は、スクリプト テキストを HTML HEAD タグに直接追加する必要があります。as として追加すると、 非同期 負荷。外部ファイルからスクリプト テキストを同期的に読み込むには、XHR を使用します。以下に簡単なサンプルを示します (この投稿と他の投稿の他の回答の一部を使用しています)。

/*sample requires an additional method for array prototype:*/

if (Array.prototype.contains === undefined) {
Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) { if (this[i] === obj) return true; }
    return false;
};
};

/*define object that will wrap our logic*/
var ScriptLoader = {
LoadedFiles: [],

LoadFile: function (url) {
    var self = this;
    if (this.LoadedFiles.contains(url)) return;

    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                self.LoadedFiles.push(url);
                self.AddScript(xhr.responseText);
            } else {
                if (console) console.error(xhr.statusText);
            }
        }
    };
    xhr.open("GET", url, false);/*last parameter defines if call is async or not*/
    xhr.send(null);
},

AddScript: function (code) {
    var oNew = document.createElement("script");
    oNew.type = "text/javascript";
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
}
};

/*Load script file. ScriptLoader will check if you try to load a file that has already been loaded (this check might be better, but I'm lazy).*/

ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
/*this will be executed right after upper lines. It requires jquery to execute. It requires a HTML input with id "tb1"*/
$(function () { alert($('#tb1').val()); });

私たちが仕事で使用しているテクニックは、AJAX リクエストを使用して JavaScript ファイルをリクエストし、その後 eval() でそのレスポンスを返すことです。プロトタイプ ライブラリを使用している場合、Ajax.Request 呼び出しでこの機能がサポートされます。

jquery は .append() 関数を使用してこれを解決しました- これを使用して完全な jquery ui パッケージをロードしました

/*
 * FILENAME : project.library.js
 * USAGE    : loads any javascript library
 */
    var dirPath = "../js/";
    var library = ["functions.js","swfobject.js","jquery.jeditable.mini.js","jquery-ui-1.8.8.custom.min.js","ui/jquery.ui.core.min.js","ui/jquery.ui.widget.min.js","ui/jquery.ui.position.min.js","ui/jquery.ui.button.min.js","ui/jquery.ui.mouse.min.js","ui/jquery.ui.dialog.min.js","ui/jquery.effects.core.min.js","ui/jquery.effects.blind.min.js","ui/jquery.effects.fade.min.js","ui/jquery.effects.slide.min.js","ui/jquery.effects.transfer.min.js"];

    for(var script in library){
        $('head').append('<script type="text/javascript" src="' + dirPath + library[script] + '"></script>');
    }

使用するには - jquery.js をインポートした後の html/php/etc の先頭に、この 1 つのファイルを含めるだけで、ライブラリ全体に読み込まれ、先頭に追加されます...

<script type="text/javascript" src="project.library.js"></script>

短く、シンプルで、メンテナンスしやすいものにしてください。:]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

function load(url)
{
    var ajax = new XMLHttpRequest();
    ajax.open('GET', url, false);
    ajax.onreadystatechange = function ()
    {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4)
        {
            switch(ajax.status)
            {
                case 200:
                    eval.apply( window, [script] );
                    console.log("library loaded: ", url);
                    break;
                default:
                    console.log("ERROR: library not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

このコードは単なる短い機能例です。 できた 任意の (または特定の) プラットフォームで完全にサポートするには、追加の機能が必要です。

と呼ばれる新しい ECMA 標準が提案されています。 動的インポート, 、最近 Chrome と Safari に組み込まれました。

const moduleSpecifier = './dir/someModule.js';

import(moduleSpecifier)
   .then(someModule => someModule.foo()); // executes foo method in someModule

この目的のために特別に設計されたスクリプトがあります。

うんうん.js Modernizr に組み込まれており、 lab.js はより最適化されています (ただし、ユーザーフレンドリーではありません)。

jquery やプロトタイプのような大きなライブラリを通じてこれを行うことはお勧めしません。スクリプト ローダーの主な利点の 1 つは、スクリプトを早期にロードできることです。jquery とすべての dom 要素がロードされるまで待つ必要はありません。スクリプトを動的にロードするかどうかを確認するチェックを実行します。

JavaScript でモジュール スクリプトをインポート/インクルードするジョブを自動化する単純なモジュールを作成しました。ぜひ試してみて、フィードバックをお寄せください。:) コードの詳細な説明については、このブログ投稿を参照してください。 http://stamat.wordpress.com/2013/04/12/javascript-require-import-include-modules/

var _rmod = _rmod || {}; //require module namespace
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark the root directory of your library, any library


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };

    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

//you can rename based on your liking. I chose require, but it can be called include or anything else that is easy for you to remember or write, except import because it is reserved for future use.
var require = function(script_name) {
    var np = script_name.split('.');
    if (np[np.length-1] === '*') {
        np.pop();
        np.push('_all');
    }

    script_name = np.join('.');
    var uri = _rmod.libpath + np.join('/')+'.js';
    if (!_rmod.loading.scripts.hasOwnProperty(script_name) 
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri, 
            _rmod.requireCallback, 
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

// ----- USAGE -----

require('ivar.util.array');
require('ivar.util.string');
require('ivar.net.*');

ready(function(){
    //do something when required scripts are loaded
});

これらすべてのサンプルを見て迷っていますが、今日はメインの .js から外部 .js をロードする必要があり、これを実行しました。

document.write("<script src='https://www.google.com/recaptcha/api.js'></script>");

ここ これはコールバックと IE サポートを備えた単純なものです。

function loadScript(url, callback) {

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState) { //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else { //Others
        script.onload = function () {
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

loadScript("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {

     //jQuery loaded
     console.log('jquery loaded');

});

ここでは、JS ファイルをロードする関数の簡単な例を示します。関連する点:

  • jQueryは必要ないので、最初にこれを使用してjQuery.jsファイルもロードできます。
  • コールバックと非同期です
  • ロードされた URL の記録をエンクロージャに保持するため、ロードが 1 回だけ行われることが保証され、ネットワークの使用が回避されます。
  • jQueryとは逆に $.ajax または $.getScript nonce を使用すると、CSP の問題を解決できます unsafe-inline. 。物件をそのまま利用する script.nonce
var getScriptOnce = function() {

    var scriptArray = []; //array of urls (closure)

    //function to defer loading of script
    return function (url, callback){
        //the array doesn't have such url
        if (scriptArray.indexOf(url) === -1){

            var script=document.createElement('script');
            script.src=url;
            var head=document.getElementsByTagName('head')[0],
                done=false;

            script.onload=script.onreadystatechange = function(){
                if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
                    done=true;
                    if (typeof callback === 'function') {
                        callback();
                    }
                    script.onload = script.onreadystatechange = null;
                    head.removeChild(script);

                    scriptArray.push(url);
                }
            };

            head.appendChild(script);
        }
    };
}();

今では、単純にそれを使用します

getScriptOnce("url_of_your_JS_file.js");

JS ライブラリのロードに 1 行以上のコードを必要としないと考えている人向けの、不条理なワンライナーです :P

await new Promise((resolve, reject) => {let js = document.createElement("script"); js.src="mylibrary.js"; js.onload=resolve; js.onerror=reject; document.body.appendChild(js)});

明らかに、インポートしたいスクリプトがモジュールの場合は、 import(...) 関数。

jscript、prototype、YUI などの主要な JavaScript ライブラリはすべて、スクリプト ファイルのロードをサポートしています。たとえば、YUI では、コアをロードした後、次の操作を実行してカレンダー コントロールをロードできます。

var loader = new YAHOO.util.YUILoader({

    require: ['calendar'], // what components?

    base: '../../build/',//where do they live?

    //filter: "DEBUG",  //use debug versions (or apply some
                        //some other filter?

    //loadOptional: true, //load all optional dependencies?

    //onSuccess is the function that YUI Loader
    //should call when all components are successfully loaded.
    onSuccess: function() {
        //Once the YUI Calendar Control and dependencies are on
        //the page, we'll verify that our target container is 
        //available in the DOM and then instantiate a default
        //calendar into it:
        YAHOO.util.Event.onAvailable("calendar_container", function() {
            var myCal = new YAHOO.widget.Calendar("mycal_id", "calendar_container");
            myCal.render();
        })
     },

    // should a failure occur, the onFailure function will be executed
    onFailure: function(o) {
        alert("error: " + YAHOO.lang.dump(o));
    }

 });

// Calculate the dependency and insert the required scripts and css resources
// into the document
loader.insert();

この質問に対する私の答えは少し遅れていることは承知していますが、ここに素晴らしい記事があります。 www.html5rocks.com - スクリプト読み込みの濁流を深く掘り下げる .

この記事では、ブラウザのサポートに関して、コンテンツのレンダリングをブロックせずに JavaScript ファイルを動的にロードする最良の方法は次の方法であると結論付けています。

という名前のスクリプトが 4 つあると考えると、 script1.js, script2.js, script3.js, script4.js それならあなたはそれを行うことができます async = false を適用します:

[
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
].forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.head.appendChild(script);
});

今、 仕様によると:まとめてダウンロードし、すべてのダウンロードが完了次第、順番に実行します。

Firefox < 3.6、Opera は次のように述べています。 この「非同期」が何なのかはわかりませんが、たまたま JS 経由で追加されたスクリプトを追加さ​​れた順序で実行しているだけです。

Safari 5.0 には次のように書かれています。 「async」は理解できますが、JSで「false」に設定することが理解できません。スクリプトが到着するとすぐに、どのような順序でも実行します。

IE < 10 の場合は次のようになります。 「async」についてはわかりませんが、「onreadystatechange」を使用する回避策はあります。

他のすべては次のように言います: 私はあなたの友人です、本に従ってこれを行うつもりです。

次に、IE < 10 の回避策を含む完全なコードを示します。

var scripts = [
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];

// Watch scripts load in IE
function stateChange() {
  // Execute as many scripts in order as we can
  var pendingScript;
  while (pendingScripts[0] && pendingScripts[0].readyState == 'loaded') {
    pendingScript = pendingScripts.shift();
    // avoid future loading events from this script (eg, if src changes)
    pendingScript.onreadystatechange = null;
    // can't just appendChild, old IE bug if element isn't closed
    firstScript.parentNode.insertBefore(pendingScript, firstScript);
  }
}

// loop through our script urls
while (src = scripts.shift()) {
  if ('async' in firstScript) { // modern browsers
    script = document.createElement('script');
    script.async = false;
    script.src = src;
    document.head.appendChild(script);
  }
  else if (firstScript.readyState) { // IE<10
    // create a script and add it to our todo pile
    script = document.createElement('script');
    pendingScripts.push(script);
    // listen for state changes
    script.onreadystatechange = stateChange;
    // must set src AFTER adding onreadystatechange listener
    // else we’ll miss the loaded event for cached scripts
    script.src = src;
  }
  else { // fall back to defer
    document.write('<script src="' + src + '" defer></'+'script>');
  }
}

いくつかのトリックと縮小を行うと、362 バイトになります

!function(e,t,r){function n(){for(;d[0]&&"loaded"==d[0][f];)c=d.shift(),c[o]=!i.parentNode.insertBefore(c,i)}for(var s,a,c,d=[],i=e.scripts[0],o="onreadystatechange",f="readyState";s=r.shift();)a=e.createElement(t),"async"in i?(a.async=!1,e.head.appendChild(a)):i[f]?(d.push(a),a[o]=n):e.write("<"+t+' src="'+s+'" defer></'+t+">"),a.src=s}(document,"script",[
  "//other-domain.com/1.js",
  "2.js"
])

このようなもの...

<script>
     $(document).ready(function() {
          $('body').append('<script src="https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places&callback=getCurrentPickupLocation" async defer><\/script>');
     });
</script>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top