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 dynamical
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 - 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);
}
}
}
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
I did basically the same thing that you did Adam, but with a slight modification to make sure I was appending to the head tag 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 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 );
}
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 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(function(){
let times = SunCalc.getTimes(new Date(), 51.5,-0.1);
console.log("Golden Hour today in London: " + times.goldenHour.getHours() + ':' + times.sunrise.getMinutes() + ". Take your pics!")
})
})()
https://caniuse.com/#feat=es6-module-dynamic-import