我为javascript创建了一个名称空间框架。我正在加载一些动态添加到HTML的插件(.js文件)。
我将尝试简化代码。
此函数用于动态加载JS。加载.js文件后调用回调函数。请考虑以下代码已经运行。
MYNAMESPACE.plugins = ["plugin1", "plugin2"];
MYNAMESPACE.getJS = {
get: function (url, callback) {
var script = document.createElement("script");
var head = document.getElementsByTagName('head')[0];
script.type = "text/javascript";
script.src = url;
head.insertBefore(script, head.firstChild)
script.onload = callback;
script.onreadystate = callback;
return script;
}
};
我有一个init函数,可以加载MYNAMESPACE.plugins中包含的插件,如下所示:
MYNAMESPACE.init = function (callback) {
for (index in MYNAMESPACE.plugins) {
plugin = MYNAMESPACE.plugins[index];
MYNAMESPACE.getJS.get(plugin + '.js', function ()
{
// This callback is executed when the js file is loaded
});
}
// Here I want to execute callback function, but after all the callbacks in the for loop have been executed. Something like: if (alljsloaded) callback();
}
在我的HTML中,我有以下脚本标记:
<html>
<head>
<script type="text/javascript">
$(document).ready(function () {
MYNAMESPACE.init();
// The following line is not executed correctlybecause init finished before the scripts are loaded and the functionOnPlugin1 is undefined.
MYNAMESPACE.functionOnPlugin1();
});
</script>
</head>
<body>
</body>
</html>
我想改变这样的事情:
<html>
<head>
<script type="text/javascript">
$(document).ready(function () {
MYNAMESPACE.init(function() { MYNAMESPACE.functionOnPlugin1(); });
});
</script>
</head>
<body>
</body>
</html>
但我不知道如何修改函数MYNAMESPACE.init(),以便在加载所有插件脚本后执行回调。
有什么想法吗?也许使用闭包。
答案 0 :(得分:3)
for(;;)
循环播放数组不 for(.. in ..)
。代码:
MYNAMESPACE.init = function (callback) {
var allPluginsLength = MYNAMESPACE.plugins.length;
var loadedCount = 0;
if (allPluginsLength === 0) callback(); // No plugins, invoke callback.
else for (var index=0; index<allPluginsLength; i++) {
plugin = MYNAMESPACE.plugins[index];
MYNAMESPACE.getJS.get(plugin + '.js', function () {
// This callback is executed when the js file is loaded
if (++loadedCount == allPluginsLength) {
callback();
}
});
}
}
此外,更改您的getJS.get
方法。目前,callback
总是在状态改变时执行,这是不可取的。为防止回调执行两次,可以使用以下命令:
script.onload = function() {
callback && callback();
callback = false;
};
// onreadystatechange instead of onreadystate, btw.
script.onreadystatechange = function() {
if (this.readyState == 'complete') {
callback && callback();
callback = false;
}
};
callback && callback()
用于确保存在回调。如果是,则调用它。callback = null
)
这是必要的,因为在加载脚本时可以触发onload
和onreadystatechange
事件。如果没有我建议的代码,将为单个脚本多次调用回调。答案 1 :(得分:1)
这样的一些变化应该有效:
MYNAMESPACE.init = function (callback) {
var remaining = MYNAMESPACE.plugins.length;
for (index in MYNAMESPACE.plugins) {
plugin = MYNAMESPACE.plugins[index];
MYNAMESPACE.getJS.get(plugin + '.js', function ()
{
// This callback is executed when the js file is loaded
remaining = remaining - 1;
if (remaining === 0)
{
callback();
}
});
}
}