-
Notifications
You must be signed in to change notification settings - Fork 2
/
script-loader.js
62 lines (55 loc) · 2.05 KB
/
script-loader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class ScriptLoader {
scripts = {};
isTrackingLoads = null;
allScriptsLoadedAt = null;
container = null;
constructor(scripts = {}) {
this.scripts = scripts;
this.container = document.createElement("div");
this.container.className = "script-loader";
if (Object.values(scripts).length) {
this.load();
}
}
trackLoads() {
if (this.isTrackingLoads) return;
this.isTrackingLoads = true;
window.addEventListener("ScriptLoaded", () => {
if (this.areAllScriptsLoaded()) {
this.allScriptsLoadedAt = performance.now();
window.dispatchEvent(new CustomEvent("AllScriptsLoaded", {detail: {loader: this}}));
}
});
}
areAllScriptsLoaded() {
return Object.values(this.scripts).every(config => config.loaded);
}
load() {
this.trackLoads();
for (let scriptURL in this.scripts) {
let config = this.scripts[scriptURL];
if (config.loaded != true) {
fetch(scriptURL, {cache: "no-store"})
.then((response) => response.text())
.then((text) => {
let script = document.createElement("script");
script.textContent = text;
this.container.append(script);
if (!this.container.parentElement && document.body) {
document.body.append(this.container);
}
config.loaded = true;
config.loadedAt = performance.now();
window.dispatchEvent(new CustomEvent("ScriptLoaded", {detail: {loader: this, src: scriptURL}}));
});
}
}
}
onAllLoaded(callback) {
if (this.areAllScriptsLoaded() && this.allScriptsLoadedAt != null) {
callback();
} else {
window.addEventListener("AllScriptsLoaded", callback);
}
}
}