假设的第三方JS供应商提供此脚本以包含在每个页面中:
(function() {
function loadAsync(){
// Inject the script.
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://example.com/3rdPartyStuff.js';
// Find a reasonable place to inject the script.
var firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
}
// Attach the script loader to the load event.
if (window.attachEvent) {
window.attachEvent('onload', loadAsync);
} else {
window.addEventListener('load', loadAsync, false);
}
})();
其他加载事件处理程序是否必须等待此脚本下载并执行才能继续,或者其他JS可以运行直到此脚本可用并准备执行?
这个问题的答案是否因浏览器而异?
答案 0 :(得分:1)
正如Pointy和Patrick在评论中解释的那样,在任何注入的脚本执行之前,load事件会完全显示出来。我写了一个演示版,在Chrome,IE和Edge中确认了这一点(之后我停止了测试)。
在JSFiddle上测试它:https://jsfiddle.net/bhh7szyh/3/
简而言之,我不必担心第三方脚本会减慢加载事件的速度。
Patrick还描述了使用async
属性添加的脚本的行为:
动态注入脚本的默认行为是,如果未设置async,则异步加载,但将其设置为false将导致现代浏览器同步执行。
测试代码:
<!DOCTYPE html>
<html>
<head>
<title>Tests</title>
<script>
(function() {
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function loadAsync(url){
// Inject the script.
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Find a reasonable place to inject the script.
var firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
}
function attach_to_load(fn) {
if (window.attachEvent) {
window.attachEvent('onload', fn);
} else {
window.addEventListener('load', fn, false);
}
}
attach_to_load(function() { sleep(5000); console.log('before injected JS'); });
attach_to_load(function() { loadAsync('https://pastebin.com/raw/g40BS6Tg') });
attach_to_load(function() { sleep(5000); console.log('after injected JS'); });
})();
</script>
</head>
<body>
<h1>Tests Happened</h1>
</body>
</html>