Necromaning.
I use this to load dependant scripts;
it works with IE8+ without adding any dependency on another library like jQuery !
var cScriptLoader = (function ()
{
function cScriptLoader(files)
{
var _this = this;
this.log = function (t)
{
console.log("ScriptLoader: " + t);
};
this.withNoCache = function (filename)
{
if (filename.indexOf("?") === -1)
filename += "?no_cache=" + new Date().getTime();
else
filename += "&no_cache=" + new Date().getTime();
return filename;
};
this.loadStyle = function (filename)
{
// HTMLLinkElement
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = _this.withNoCache(filename);
_this.log('Loading style ' + filename);
link.onload = function ()
{
_this.log('Loaded style "' + filename + '".');
};
link.onerror = function ()
{
_this.log('Error loading style "' + filename + '".');
};
_this.m_head.appendChild(link);
};
this.loadScript = function (i)
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = _this.withNoCache(_this.m_js_files[i]);
var loadNextScript = function ()
{
if (i + 1 < _this.m_js_files.length)
{
_this.loadScript(i + 1);
}
};
script.onload = function ()
{
_this.log('Loaded script "' + _this.m_js_files[i] + '".');
loadNextScript();
};
script.onerror = function ()
{
_this.log('Error loading script "' + _this.m_js_files[i] + '".');
loadNextScript();
};
_this.log('Loading script "' + _this.m_js_files[i] + '".');
_this.m_head.appendChild(script);
};
this.loadFiles = function ()
{
// this.log(this.m_css_files);
// this.log(this.m_js_files);
for (var i = 0; i < _this.m_css_files.length; ++i)
_this.loadStyle(_this.m_css_files[i]);
_this.loadScript(0);
};
this.m_js_files = [];
this.m_css_files = [];
this.m_head = document.getElementsByTagName("head")[0];
// this.m_head = document.head; // IE9+ only
function endsWith(str, suffix)
{
if (str === null || suffix === null)
return false;
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
for (var i = 0; i < files.length; ++i)
{
if (endsWith(files[i], ".css"))
{
this.m_css_files.push(files[i]);
}
else if (endsWith(files[i], ".js"))
{
this.m_js_files.push(files[i]);
}
else
this.log('Error unknown filetype "' + files[i] + '".');
}
}
return cScriptLoader;
})();
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
If you are interested in the typescript-version used to create this:
class cScriptLoader {
private m_js_files: string[];
private m_css_files: string[];
private m_head:HTMLHeadElement;
private log = (t:any) =>
{
console.log("ScriptLoader: " + t);
}
constructor(files: string[]) {
this.m_js_files = [];
this.m_css_files = [];
this.m_head = document.getElementsByTagName("head")[0];
// this.m_head = document.head; // IE9+ only
function endsWith(str:string, suffix:string):boolean
{
if(str === null || suffix === null)
return false;
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
for(let i:number = 0; i < files.length; ++i)
{
if(endsWith(files[i], ".css"))
{
this.m_css_files.push(files[i]);
}
else if(endsWith(files[i], ".js"))
{
this.m_js_files.push(files[i]);
}
else
this.log('Error unknown filetype "' + files[i] +'".');
}
}
public withNoCache = (filename:string):string =>
{
if(filename.indexOf("?") === -1)
filename += "?no_cache=" + new Date().getTime();
else
filename += "&no_cache=" + new Date().getTime();
return filename;
}
public loadStyle = (filename:string) =>
{
// HTMLLinkElement
let link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = this.withNoCache(filename);
this.log('Loading style ' + filename);
link.onload = () =>
{
this.log('Loaded style "' + filename + '".');
};
link.onerror = () =>
{
this.log('Error loading style "' + filename + '".');
};
this.m_head.appendChild(link);
}
public loadScript = (i:number) =>
{
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.withNoCache(this.m_js_files[i]);
var loadNextScript = () =>
{
if (i + 1 < this.m_js_files.length)
{
this.loadScript(i + 1);
}
}
script.onload = () =>
{
this.log('Loaded script "' + this.m_js_files[i] + '".');
loadNextScript();
};
script.onerror = () =>
{
this.log('Error loading script "' + this.m_js_files[i] + '".');
loadNextScript();
};
this.log('Loading script "' + this.m_js_files[i] + '".');
this.m_head.appendChild(script);
}
public loadFiles = () =>
{
// this.log(this.m_css_files);
// this.log(this.m_js_files);
for(let i:number = 0; i < this.m_css_files.length; ++i)
this.loadStyle(this.m_css_files[i])
this.loadScript(0);
}
}
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
If it's to load a dynamic list of scripts, write the scripts into an attribute, such as data-main, e.g.
<script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
and do a element.getAttribute("data-main").split(',')
such as
var target = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
// Note: this is for IE as IE doesn't support currentScript
// this does not work if you have deferred loading with async
// e.g. <script src="..." async="async" ></script>
// https://web.archive.org/web/20180618155601/https://www.w3schools.com/TAgs/att_script_async.asp
return scripts[scripts.length - 1];
})();
target.getAttribute("data-main").split(',')
to obtain the list.