我正在尝试构建一个相当简单的javascript加载器机制。我知道有更多的libs可以做得更好,但我想我可以通过自己尝试来学习。
下面是我的(简化)代码。我的目标是在一个地方保留对所有不同js文件(mod)的引用,即_Mods
对象。加载脚本标记后,它将发送代码侦听的自定义事件,并将自己的mod数据(来自_Mods
对象)作为参数。每次收到该自定义事件时,计划都将该mod标记为已加载,并最终声明所有mod已加载。然后继续。
我的问题是,当我运行此代码时,控制台将打印mod 'word' loaded!
一次,然后退出。如果我在运行!mod.callback.done
之前注释掉callback()
条件,则会打印mod 'word' loaded!
三次。
因此,我意识到mod
变量会为每个应该加载的新mod重新分配,并且在加载脚本时应该进行回调,指向前两个mods的数据对象的指针迷路了。
我有什么建议可以重构这个以便从三个不同的 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);
答案 0 :(得分:1)
尝试这样的事情:
scriptTag.onreadystatechange = scriptTag.onload = (function(mod) {
return function(){
var state = scriptTag.readyState;
if (!mod.callback.done && (!state || /loaded|complete/.test(state))) {
mod.callback.done = true;
mod.callback();
}
};
})(mod);