Динамически загружать файл JavaScript

Как вы можете надежно и динамически загружать файл JavaScript? Это можно использовать для реализации модуля или компонента, который при инициализации компонента будет динамически загружать все необходимые скрипты библиотеки JavaScript по запросу.

Клиент, который использует этот компонент, не обязан загружать все библиотеки script файлов (и вручную вставлять теги <script> на свою веб-страницу), которые реализуют этот компонент - только файл 'main' script.

Как реализуются основные библиотеки JavaScript (Prototype, jQuery и т.д.)?. Свертывают ли эти инструменты несколько файлов JavaScript в одну распространяемую версию 'build' файла script? Или они выполняют динамическую загрузку сценариев вспомогательной библиотеки?

В дополнение к этому вопросу: есть способ обработать событие после загрузки динамически включенного файла JavaScript?. Прототип имеет document.observe для событий в рамках всего документа. Пример:

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

Каковы доступные события для элемента script?

Ответы

Ответ 1

Вы можете писать динамические теги script (используя Prototype):

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

Проблема заключается в том, что мы не знаем, когда загружен внешний файл script.

Мы часто хотим, чтобы наш зависимый код находился на самой следующей строке и хотел написать что-то вроде:

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

Существует разумный способ вложения зависимостей script без необходимости обратных вызовов. Вам просто нужно вытащить script через синхронный запрос AJAX и оценить script на глобальном уровне.

Если вы используете 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);
    }
};

Ответ 2

В javascript нет импорта /include/require, но есть два основных способа достижения того, что вы хотите:

1 - Вы можете загрузить его с помощью вызова AJAX, а затем использовать eval.

Это самый простой способ, но он ограничен вашим доменом из-за настроек безопасности Javascript, и использование eval открывает дверь для ошибок и хаков.

2. Добавьте тег script с URL script в HTML.

Определенно лучший способ. Вы можете загрузить script даже с внешнего сервера, и он очищается, когда вы используете анализатор браузера для оценки кода. Вы можете поместить тег в начало веб-страницы или в нижней части тела.

Оба этих решения обсуждаются и проиллюстрированы здесь.

Теперь есть большая проблема, о которой вы должны знать. Это означает, что вы дистанционно загружаете код. Современные веб-браузеры загружают файл и продолжают выполнять текущий script, потому что они загружают все асинхронно, чтобы улучшить производительность.

Это означает, что если вы используете эти трюки напрямую, вы не сможете использовать свой недавно загруженный код на следующей строке после того, как вы попросите его загрузить, потому что он будет по-прежнему загружаться.

E.G: 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 event для запуска функции обратного вызова при загрузке script. Таким образом, вы можете поместить весь код с помощью удаленной библиотеки в функцию обратного вызова. E.G:

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

Затем вы пишете код, который хотите использовать ПОСЛЕ того, как script загружается в лямбда-функцию:

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

Затем вы запустите все это:

loadScript("my_lovely_script.js", myPrettyCode);

Хорошо, я понял. Но это боль, чтобы написать все это.

Ну, в таком случае вы можете использовать как всегда фантастическую бесплатную фреймворк jQuery, которая позволяет делать одно и то же в одной строке:

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

Ответ 3

Я использовал гораздо менее сложную версию в последнее время с 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-less:

<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>

Ответ 4

Я сделал в основном то же самое, что и Адам, но с небольшим изменением, чтобы убедиться, что я добавляю к тегу head, чтобы выполнить эту работу. Я просто создал функцию include (код ниже) для обработки как файлов сценариев, так и css.

Эта функция также проверяет, чтобы файл сценария или 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 );
}

Ответ 5

еще один удивительный ответ

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


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

 });

fooobar.com/questions/117/...

Ответ 6

Вот пример кода, который я нашел... у кого-то есть лучший способ?

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

Ответ 7

Если у вас уже загружен jQuery, вы должны использовать $. getScript.

Это имеет преимущество перед другими ответами здесь, поскольку у вас есть встроенная функция обратного вызова (чтобы гарантировать загрузку script до запуска зависимого кода), и вы можете управлять кэшированием.

Ответ 8

У кого-нибудь есть лучший способ?

Я думаю, что просто добавление script к телу было бы проще, а затем добавить его к последнему node на странице. Как насчет этого:

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

Ответ 9

Я использовал еще одно решение, которое я нашел в сети... этот находится под creativecommons, и он проверяет, был ли источник включен до вызова функции...

вы можете найти файл здесь: include.js

/** include - including .js files from JS - [email protected] - 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);
    }
  }   
} 

Ответ 10

Только что узнал о отличной функции в YUI 3 (на момент написания, доступной в предварительном выпуске). Вы можете легко вставлять зависимости в библиотеки YUI и "внешние" модули (что вы ищете) без особого кода: YUI Loader.

Он также отвечает на ваш второй вопрос относительно вызываемой функции, как только загружается внешний модуль.

Пример:

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.

Ответ 11

Если вы хотите загрузить SYNC script, вам нужно добавить текст script непосредственно в тег HTML HEAD. Добавление этого параметра приведет к загрузке ASYNC. Чтобы загрузить текст script из внешнего файла синхронно, используйте 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()); });

Ответ 12

Там был предложен новый стандарт ECMA, называемый динамическим импортом, недавно включенный в Chrome и Safari.

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

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

Ответ 13

Техника, которую мы используем на работе, - это запросить файл javascript, используя запрос AJAX, а затем eval() return. Если вы используете библиотеку прототипов, они поддерживают эту функцию в своем вызове Ajax.Request.

Ответ 14

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

Использовать - в начале вашего html/php/etc после импорта jquery.js вы просто включили бы этот один файл, чтобы загрузить всю вашу библиотеку, добавив ее в голова...

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

Ответ 15

Держите это красивым, коротким, простым и удобным для обслуживания!:]

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

Этот код является просто небольшим функциональным примером, который может потребовать дополнительных функциональных возможностей для полной поддержки на любой (или данной) платформе.

Ответ 16

Существуют сценарии, специально разработанные для этой цели.

yepnope.js встроен в Modernizr и lab.js является более оптимизированной (но менее удобной для пользователя версией).

Я бы не рекомендовал делать это через большую библиотеку, такую ​​как jquery или prototype, потому что одним из основных преимуществ загрузчика script является возможность загрузки скриптов раньше - вам не придется ждать, пока jquery и все загрузите элементы вашего дома перед запуском проверки, чтобы увидеть, хотите ли вы динамически загружать script.

Ответ 17

Я написал простой модуль, который автоматизирует работу по импорту/включая скрипты модулей в 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
});

Ответ 18

Я потерялся во всех этих образцах, но сегодня мне нужно было загрузить внешний .js из моего основного .js, и я сделал это:

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

Ответ 19

Здесь является простой с обратным вызовом и поддержкой 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');

});

Ответ 20

Я знаю, что мой ответ немного запоздал для этого вопроса, но вот замечательная статья в www.html5rocks.com - Глубокое погружение в мутные воды script загрузки.

В этой статье делается вывод, что в отношении поддержки браузера лучший способ динамически загружать файл JavaScript без блокировки рендеринга содержимого выглядит следующим образом:

Учитывая, что у вас есть четыре сценария с именем 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);
});

Теперь Spec говорит: скачайте вместе, выполните в порядке, как только все будет загружено.

Firefox < 3.6, Opera говорит: Я понятия не имею, что это за "асинхронная" вещь, но так бывает. Я запускаю скрипты, добавленные через JS в том порядке, в котором они добавлены.

Safari 5.0 говорит: Я понимаю "асинхронный", но не понимаю, как установить его "false" с помощью JS. Я выполняю ваши сценарии, как только они приземлятся, в любом порядке.

IE < 10 говорит: Не знаю, как "асинхронно", но есть обходное решение, использующее "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"
])

Ответ 21

Что-то вроде этого...

<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>

Ответ 22

Вот простой пример для функции загрузки JS файлов. Соответствующие пункты:

  • вам не нужен jQuery, поэтому вы можете сначала использовать это для загрузки файла jQuery.js
  • это асинхронно с обратным вызовом
  • он гарантирует, что он загружается только один раз, поскольку он хранит оболочку с записью загруженных URL-адресов, что позволяет избежать использования сети
  • в отличие от jQuery $.ajax или $.getScript вы можете использовать nonces, решая, таким образом, проблемы с 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");

Ответ 23

Абсурдный однострочный, для тех, кто считает, что загрузка библиотеки js не должна содержать более одной строки кода: 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(...).

Ответ 25

все основные библиотеки javascript, такие как jscript, prototype, YUI, поддерживают загрузку файлов script. Например, в 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();