我正在尝试构建我自己的一个相当简单的 javascript 加载器机制。我知道有很多库做得更好,但我认为我可以通过自己尝试来学习一些东西。
下面是我的(简化的)代码。我的目标是将所有不同 js 文件(mod)的引用保存在一个地方,即_Mods
对象。加载脚本标签后,它将发送代码监听的自定义事件,并以自己的 mod 数据(来自_Mods
对象)作为参数。每次收到该自定义事件时,计划将该模块标记为已加载,并最终声明所有模块已加载。然后继续。
我的问题是,当我运行此代码时,控制台将打印mod 'word' loaded!
一次然后退出。如果我在运行之前注释掉!mod.callback.done
条件,callback()
它将打印mod 'word' loaded!
三遍。
因此,我意识到该mod
变量会为每个应该加载的新模块重新分配,并且在加载脚本并应该进行回调时,指向前两个模块数据对象的指针丢失了。
有什么建议我可以重构它以便从三个不同的mod 中获取回调?
(function(window) {
var ModLoader = (function() {
var _Mods = {
game: {
name: "game",
src: "js/GameEngine.js"
},
dictionary: {
name: "dictionary",
src: "js/Dictionary.js"
},
word: {
name: "word",
src: "js/Word.js"
}
},
_loadMods = function() {
var head = document.getElementsByTagName('HEAD').item(0);
for (var property in _Mods) {
if (_Mods.hasOwnProperty(property)) {
var mod = _Mods[property],
scriptTag = document.createElement("script");
scriptTag.setAttribute("type", "text/javascript");
scriptTag.src = mod.src;
mod.callback = function() {
var customEvent = document.createEvent("Events");
customEvent.initEvent("ModLoaded", true, true);
customEvent.mod = mod;
window.dispatchEvent(customEvent);
};
scriptTag.onreadystatechange = scriptTag.onload = function() {
var state = scriptTag.readyState;
if (!mod.callback.done && (!state || /loaded|complete/.test(state))) {
mod.callback.done = true;
mod.callback();
}
};
(document.body || head).appendChild(scriptTag);
}
}
},
_modLoaded = function(event) {
console.log("mod '" + event.mod.name + "' loaded!");
};
return {
loadMods: _loadMods,
modLoaded: _modLoaded
};
})();
window.addEventListener("ModLoaded", ModLoader.modLoaded, false);
ModLoader.loadMods();
})(window);