以下是我的问题的简化版本。为什么loaded
回调没有被解雇?
我的目标是将一个脚本文件(我无法通过src
引用)注入文档的head
标记:
(function(module, scriptContent, loaded) {
if (!window[module]) {
var script = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
if (script.readyState) {
script.onreadystatechange = function() {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
loaded();
}
};
} else {
script.onload = loaded;
}
script.appendChild(document.createTextNode(scriptContent));
head.appendChild(script);
} else {
loaded();
}
})('foo', 'var foo = {};', function(){
console.log('loaded');
});
答案 0 :(得分:1)
因为内联脚本是同步运行的,所以不要使用readyState
。
这可以通过将您的'var foo = {};'
更改为'console.log("b")'
,之前添加console.log('a')
以及console.log('c')
之后添加head.appendChild(script);
来证明:
(function(module, scriptContent, loaded) {
if (!window[module]) {
var script = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
if (script.readyState) {
script.onreadystatechange = function() {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
loaded();
}
};
} else {
script.onload = loaded;
}
script.appendChild(document.createTextNode(scriptContent));
console.log('a');
head.appendChild(script);
console.log('c');
} else {
loaded();
}
})('foo', 'console.log("b")', function(){
console.log('loaded');
});
请注意它们是按字母顺序记录的 如果插入的脚本是异步加载的,那么创建它的调用堆栈必须先终止,这将导致在“b”之前记录“a”和“c”。
换句话说,您可以在loaded()
之后立即致电head.appendChild(script);
。