我正在动态加载多个javascript引用,并向DOM添加脚本标记。
感谢您帮助解释脚本加载行为。
我假设的是,当我将脚本元素附加到DOM时,脚本会被下载然后执行。但是当.onload
事件被触发时?脚本一开始执行或完成执行后立即执行?如果第二个为真,那么如何等待脚本执行/初始化(我想执行回调,它会附加带有依赖于动态加载引用的脚本的附加html)?
要加载脚本我使用以下功能:
function recursiveInclude(scriptPathArray, callback) {
if (scriptPathArray.length > 0) {
var scriptPath = scriptPathArray[0];
// check if script is already loaded if not load
// this_loadedScriptList is one scope level up variable
if (this_loadedScriptList.indexOf(scriptPath) > 0 == false) {
var body = document.getElementsByTagName('body')[0];
var scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.src = scriptPath;
// first script from the array will loaded as soon as body.appendChild function will be called
// when script loads 'onload' event will fire next script loading
// to this work properly first script from scriptPathArray has to be removed:
scriptPathArray.shift();
// if there are any other scripts to load, load them sequentially
if (scriptPathArray.length > 0) {
// then bind the event to the callback function
// there are several events for cross browser compatibility
// script.onreadystatechange = callback;
scriptElement.onload = recursiveInclude(scriptPathArray, callback);
} else {
// if no other scripts to load - fire base callback;
scriptElement.onload = callback;
}
// fire the loading
body.appendChild(scriptElement);
// add script to loaded array.
this_loadedScriptList.push(scriptPath);
}
}
}
答案 0 :(得分:1)
JavaScript既不是线程也不是事件中断。在其他任何事情发生之前执行漏洞脚本。捕获事件直到浏览器恢复控制。因此onload
或任何其他事件只能在脚本执行完成之前或之后触发。实际上{/ 1}在执行后被解雇。
firefox仍支持事件onload
,但已从HTML5.1规范中删除。
你可以自己尝试一下:
beforescriptexecute
external.js:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
console.log('base script start');
var script=document.createElement('script');
script.onload = function() { console.log('onload fired'); }
// MDN says:
// This event was a proposal in an early version of the specification. Do not rely on it.
//
script.addEventListener('beforescriptexecute', function () { console.log('beforescriptexecute fired'); });
script.src = 'external.js';
document.head.appendChild(script);
console.log('waiting 3 seconds');
timebase = Date.now();
while((Date.now() - timebase) < 3000)
;
console.log("base script end");
</script>
</body>
</html>
基本脚本开始
等待3秒
基本脚本结束
beforescriptexecute解雇了 外部开始...等待3秒
外端
onload炒了
答案 1 :(得分:1)
你必须知道一个大问题。这样做意味着您远程加载代码。现代Web浏览器将加载文件并继续执行当前脚本,因为它们异步加载所有内容以提高性能。 (这适用于jQuery方法和手动动态脚本加载方法。)
这意味着如果您直接使用这些技巧,在您要求加载后,您将无法在下一行使用新加载的代码,因为它仍将加载。
实际上,您所能做的就是在加载脚本时使用事件来运行回调函数。
function loadScript(url, callback)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
然后编写如下代码:
var myCode = function() {
...
};
最后你可以运行它:
loadScript("the-remote-script.js", myCode);