Dynamically load a JavaScript file

JavascriptFileImportInclude

Javascript Problem Overview


How can you reliably and dynamically load a JavaScript file? This will can be used to implement a module or component that when 'initialized' the component will dynamically load all needed JavaScript library scripts on demand.

The client that uses the component isn't required to load all the library script files (and manually insert <script> tags into their web page) that implement this component - just the 'main' component script file.

How do mainstream JavaScript libraries accomplish this (Prototype, jQuery, etc)? Do these tools merge multiple JavaScript files into a single redistributable 'build' version of a script file? Or do they do any dynamic loading of ancillary 'library' scripts?

An addition to this question: is there a way to handle the event after a dynamically included JavaScript file is loaded? Prototype has document.observe for document-wide events. Example:

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

What are the available events for a script element?

Javascript Solutions


Solution 1 - Javascript

You may create a script element dynamically, using Prototypes:

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

The problem here is that we do not know when the external script file is fully loaded.

We often want our dependant code on the very next line and like to write something like:

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

There is a smart way to inject script dependencies without the need of callbacks. You simply have to pull the script via a synchronous AJAX request and eval the script on global level.

If you use Prototype the Script.load method looks like this:

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

Solution 2 - Javascript

There is no import / include / require in javascript, but there are two main ways to achieve what you want:

1 - You can load it with an AJAX call then use eval.

This is the most straightforward way but it's limited to your domain because of the Javascript safety settings, and using eval is opening the door to bugs and hacks.

2 - Add a script element with the script URL in the HTML.

Definitely the best way to go. You can load the script even from a foreign server, and it's clean as you use the browser parser to evaluate the code. You can put the script element in the head element of the web page, or at the bottom of the body.

Both of these solutions are discussed and illustrated here.

Now, there is a big issue you must know about. Doing that implies that you remotely load the code. Modern web browsers will load the file and keep executing your current script because they load everything asynchronously to improve performances.

It means that if you use these tricks directly, you won't be able to use your newly loaded code the next line after you asked it to be loaded, because it will be still loading.

E.G : my_lovely_script.js contains 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

Then you reload the page hitting F5. And it works! Confusing...

So what to do about it ?

Well, you can use the hack the author suggests in the link I gave you. In summary, for people in a hurry, he uses en event to run a callback function when the script is loaded. So you can put all the code using the remote library in the callback function. E.G :

function loadScript(url, callback)
{
    // adding the script element 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);
}

Then you write the code you want to use AFTER the script is loaded in a lambda function :

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

Then you run all that :

loadScript("my_lovely_script.js", myPrettyCode);

Ok, I got it. But it's a pain to write all this stuff.

Well, in that case, you can use as always the fantastic free jQuery framework, which let you do the very same thing in one line :

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

Solution 3 - Javascript

I used a much less complicated version recently with 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>

It worked great in every browser I tested it in: IE6/7, Firefox, Safari, Opera.

Update: jQuery-less version:

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

Solution 4 - Javascript

I did basically the same thing that you did Adam, but with a slight modification to make sure I was appending to the head element to get the job done. I simply created an include function (code below) to handle both script and CSS files.

This function also checks to make sure that the script or CSS file hasn't already been loaded dynamically. It does not check for hand coded values and there may have been a better way to do that, but it served the purpose.

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 element = null;
    switch( type ){
        case 'text/javascript' :
            element = document.createElement( 'script' );
            element.type = type;
            element.src = url;
            break;
        case 'text/css' :
            element = document.createElement( 'link' );
            element.rel = 'stylesheet';
            element.type = type;
            element.href = url;
            break;
    }
    
    // Insert it to the <head> and the array to ensure it is not
    // loaded again.
    document.getElementsByTagName("head")[0].appendChild( element );
    Array.add( includedFile, url );
}

Solution 5 - Javascript

another awesome answer

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

Solution 6 - Javascript

Here is some example code I've found... does anyone have a better way?

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

Solution 7 - Javascript

Dynamic module import landed in Firefox 67+.

(async () => {
   await import('./synth/BubbleSynth.js')
})()

With error handling:

(async () => {
    await import('./synth/BubbleSynth.js').catch((error) => console.log('Loading failed' + error))
})()

It also works for any kind of non-modules libraries, on this case the lib is available on the window.self object, the old way, but only on demand, which is nice.

Example using suncalc.js, the server must have CORS enabled to works this way!

(async () => {
 await import('https://cdnjs.cloudflare.com/ajax/libs/suncalc/1.8.0/suncalc.min.js')
 .then( () => {
   let times = SunCalc.getTimes(new Date(), 51.5,-0.1);
   console.log("Golden Hour today in London: " + times.goldenHour.getHours() + ':' + times.goldenHour.getMinutes() + ". Take your pics!")
  })
})()

https://caniuse.com/#feat=es6-module-dynamic-import

Solution 8 - Javascript

If you have jQuery loaded already, you should use $.getScript.

This has an advantage over the other answers here in that you have a built in callback function (to guarantee the script is loaded before the dependant code runs) and you can control caching.

Solution 9 - Javascript

If you want a SYNC script loading, you need to add script text directly to HTML HEAD element. Adding it as

Solution 10 - Javascript

> does anyone have a better way?

I think just adding the script to the body would be easier then adding it to the last node on the page. How about this:

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

Solution 11 - Javascript

i've used yet another solution i found on the net ... this one is under creativecommons and it checks if the source was included prior to calling the function ...

you can find the file here: 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);
    }
  }   
} 

Solution 12 - Javascript

Just found out about a great feature in YUI 3 (at the time of writing available in preview release). You can easily insert dependencies to YUI libraries and to "external" modules (what you are looking for) without too much code: YUI Loader.

It also answers your second question regarding the function being called as soon as the external module is loaded.

Example:

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

Worked perfectly for me and has the advantage of managing dependencies. Refer to the YUI documentation for an example with YUI 2 calendar.

Solution 13 - Javascript

I know my answer is bit late for this question, but, here is a great article in www.html5rocks.com - Deep dive into the murky waters of script loading .

In that article it is concluded that in regards of browser support, the best way to dynamically load JavaScript file without blocking content rendering is the following way:

Considering you've four scripts named script1.js, script2.js, script3.js, script4.js then you can do it with applying 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);
});

Now, Spec says: Download together, execute in order as soon as all download.

Firefox < 3.6, Opera says: I have no idea what this “async” thing is, but it just so happens I execute scripts added via JS in the order they’re added.

Safari 5.0 says: I understand “async”, but don’t understand setting it to “false” with JS. I’ll execute your scripts as soon as they land, in whatever order.

IE < 10 says: No idea about “async”, but there is a workaround using “onreadystatechange”.

Everything else says: I’m your friend, we’re going to do this by the book.

Now, the full code with IE < 10 workaround:

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

A few tricks and minification later, it’s 362 bytes

!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"])

Solution 14 - Javascript

There's a new proposed ECMA standard called dynamic import, recently incorporated into Chrome and Safari.

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

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

Solution 15 - Javascript

With Promises you can simplify it like this. Loader function:

  const loadCDN = src =>
    new Promise((resolve, reject) => {
      if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve()
      const script = document.createElement("script")
      script.src = src
      script.async = true
      document.head.appendChild(script)
      script.onload = resolve
      script.onerror = reject
    })

Usage (async/await):

await loadCDN("https://.../script.js")

Usage (Promise):

loadCDN("https://.../script.js").then(res => {}).catch(err => {})

NOTE: there was one similar solution but it doesn't check if the script is already loaded and loads the script each time. This one checks src property.

Solution 16 - Javascript

The technique we use at work is to request the javascript file using an AJAX request and then eval() the return. If you're using the prototype library, they support this functionality in their Ajax.Request call.

Solution 17 - Javascript

jquery resolved this for me with its .append() function

  • used this to load the complete jquery ui package

    /*

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

To Use - in the head of your html/php/etc after you import jquery.js you would just include this one file like so to load in the entirety of your library appending it to the head...

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

Solution 18 - Javascript

Keep it nice, short, simple, and maintainable! :]

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

This code is simply a short functional example that could require additional feature functionality for full support on any (or given) platform.

Solution 19 - Javascript

Something like this...

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

Solution 20 - Javascript

There are scripts that are designed specifically for this purpose.

yepnope.js is built into Modernizr, and lab.js is a more optimized (but less user friendly version.

I wouldn't reccomend doing this through a big library like jquery or prototype - because one of the major benefits of a script loader is the ability to load scripts early - you shouldn't have to wait until jquery & all your dom elements load before running a check to see if you want to dynamically load a script.

Solution 21 - Javascript

I wrote a simple module that automatizes the job of importing/including module scripts in JavaScript. Give it a try and please spare some feedback! :) For detailed explanation of the code refer to this blog post: 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
});

Solution 22 - Javascript

I am lost in all these samples but today I needed to load an external .js from my main .js and I did this:

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

Solution 23 - Javascript

Here is a simple one with callback and IE support:

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

});

Solution 24 - Javascript

Here a simple example for a function to load JS files. Relevant points:

  • you don't need jQuery, so you may use this initially to load also the jQuery.js file
  • it is async with callback
  • it ensures it loads only once, as it keeps an enclosure with the record of loaded urls, thus avoiding usage of network
  • contrary to jQuery $.ajax or $.getScript you can use nonces, solving thus issues with CSP unsafe-inline. Just use the property 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);
        }
    };
}();

Now you use it simply by

getScriptOnce("url_of_your_JS_file.js");

Solution 25 - Javascript

An absurd one-liner, for those who think that loading a js library shouldn't take more than one line of code :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)});

Obviously if the script you want to import is a module, you can use the import(...) function.

Solution 26 - Javascript

For those of you, who love one-liners:

import('./myscript.js');

Chances are you might get an error, like:

> Access to script at 'http://..../myscript.js' from origin > 'http://127.0.0.1'; has been blocked by CORS policy: No > 'Access-Control-Allow-Origin' header is present on the requested > resource.

In which case, you can fallback to:

fetch('myscript.js').then(r => r.text()).then(t => new Function(t)());

Solution 27 - Javascript

In as much as I love how handy the JQuery approach is, the JavaScript approach isn't that complicated but just require little tweaking to what you already use... Here is how I load JS dynamically(Only when needed), and wait for them to load before executing the script that depends on them.

JavaScript Approach

//Create a script element that will load
let dynamicScript = document.createElement('script');

//Set source to the script we need to load
dynamicScript.src = 'linkToNeededJsFile.js';

//Set onload to callback function that depends on this script or do inline as shown below
dynamicScript.onload = () => {

    //Code that depends on the loaded script should be here

};

//append the created script element to body element
document.body.append(dynamicScript);

There are other ways approach one could accomplish this with JS but, I prefer this as it's require the basic JS knowledge every dev can relate.

Not part of the answer but here is the JQuery version I prefer with projects that already include JQuery:

$.getScript('linkToNeededJsFile.js', () => {

    //Code that depends on the loaded script should be here

});

More on the JQuery option here

Solution 28 - Javascript

all the major javascript libraries like jscript, prototype, YUI have support for loading script files. For example, in YUI, after loading the core you can do the following to load the calendar control

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

Solution 29 - Javascript

I have tweaked some of the above post with working example. Here we can give css and js in same array also.

$(document).ready(function(){

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 jsScriptCssLoader = {
		
jsExpr : new RegExp( "js$", "i" ),
cssExpr : new RegExp( "css$", "i" ),
loadedFiles: [],

loadFile: function (cssJsFileArray) {
    var self = this;
    // remove duplicates with in array
    cssJsFileArray.filter((item,index)=>cssJsFileArray.indexOf(item)==index)
    var loadedFileArray = this.loadedFiles;
    $.each(cssJsFileArray, function( index, url ) {
    	    // if multiple arrays are loaded the check the uniqueness
    		if (loadedFileArray.contains(url)) return;
    	    if( self.jsExpr.test( url ) ){
    	    	$.get(url, function(data) {
    	    		self.addScript(data);
    	    	});
    	    	  
    	    }else if( self.cssExpr.test( url ) ){
    	    	$.get(url, function(data) {
    	    		self.addCss(data);
    	    	});
    	    }
    	    
    	    self.loadedFiles.push(url);
    });
    
    // don't load twice accross different arrays
    
},
addScript: function (code) {
    var oNew = document.createElement("script");
    oNew.type = "text/javascript";
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
},
addCss: function (code) {
    var oNew = document.createElement("style");
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
}

};


//jsScriptCssLoader.loadFile(["css/1.css","css/2.css","css/3.css"]);
jsScriptCssLoader.loadFile(["js/common/1.js","js/2.js","js/common/file/fileReader.js"]);
});

Solution 30 - Javascript

This function uses memorization. And could be called many times with no conflicts of loading and running the same script twice. Also it's not resolving sooner than the script is actually loaded (like in @radulle answer).

const loadScript = function (src) {
    let cache = [];
    return function (src) {
        return cache[src] || (cache[src] = new Promise((resolve, reject) => {
            let s = document.createElement('script');
            s.defer = true;
            s.src = src;
            s.onload = resolve;
            s.onerror = reject;
            document.head.append(s);
        }));
    }
}();

Please notice the parentheses () after the function expression.

Parallel loading of scripts:

Promise.all([
    loadScript('/script1.js'),
    loadScript('/script2.js'),
    // ...
]).then(() => {
    // do something
})

You can use the same method for dynamic loading stylesheets.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdamView Question on Stackoverflow
Solution 1 - JavascriptaemkeiView Answer on Stackoverflow
Solution 2 - JavascriptanonView Answer on Stackoverflow
Solution 3 - JavascripttravisView Answer on Stackoverflow
Solution 4 - JavascriptpalehorseView Answer on Stackoverflow
Solution 5 - JavascriptNaveedView Answer on Stackoverflow
Solution 6 - JavascriptAdamView Answer on Stackoverflow
Solution 7 - JavascriptNVRMView Answer on Stackoverflow
Solution 8 - JavascriptMuhdView Answer on Stackoverflow
Solution 9 - JavascriptSieluView Answer on Stackoverflow
Solution 10 - JavascriptJoseph PecoraroView Answer on Stackoverflow
Solution 11 - JavascriptPierre SpringView Answer on Stackoverflow
Solution 12 - JavascriptKariemView Answer on Stackoverflow
Solution 13 - JavascriptasmmahmudView Answer on Stackoverflow
Solution 14 - JavascriptAlisterView Answer on Stackoverflow
Solution 15 - JavascriptradulleView Answer on Stackoverflow
Solution 16 - Javascript17 of 26View Answer on Stackoverflow
Solution 17 - JavascriptJM DesignView Answer on Stackoverflow
Solution 18 - JavascripttfontView Answer on Stackoverflow
Solution 19 - JavascriptJames ArnoldView Answer on Stackoverflow
Solution 20 - Javascript1nfinitiView Answer on Stackoverflow
Solution 21 - JavascriptstamatView Answer on Stackoverflow
Solution 22 - JavascriptadrianTNTView Answer on Stackoverflow
Solution 23 - JavascriptJacobView Answer on Stackoverflow
Solution 24 - JavascriptJoão Pimentel FerreiraView Answer on Stackoverflow
Solution 25 - Javascriptuser993683View Answer on Stackoverflow
Solution 26 - JavascriptLudmil TinkovView Answer on Stackoverflow
Solution 27 - JavascriptEnricoView Answer on Stackoverflow
Solution 28 - JavascriptDarren KoppView Answer on Stackoverflow
Solution 29 - JavascriptVG PView Answer on Stackoverflow
Solution 30 - JavascriptvatavaleView Answer on Stackoverflow