我创建了下面的示例,其中页面在HTML页面的底部动态加载temp.js。 temp.js有一个小睡眠功能,在记录'Script Loaded'之前将浏览器绑定3秒钟。在HTML页面的最底部,它记录了一个“页面加载”
现在,了解我对浏览器的了解,下载资源以及JS的单线程特性我认为会发生这种情况。
但实际上发生的是这个
这是你期望的行为吗?
function sleep (ms) {
var now = (new Date()).getTime ();
while ((now + ms) > ((new Date()).getTime ())) {
}
}
sleep (3000);
console.log ('Script Loaded');
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>querySelectorAll</title>
</head>
<body>
<ul>
<li><a href="">One</a></li>
<li><a href="">Two</a></li>
</ul>
<div id="nick">
<img src="image.png" alt="" width="10" height="10" />
<img src="image.png" alt="" width="10" height="10" />
<img src="image.png" alt="" width="10" height="10" />
</div>
<!-- <script type="text/javascript" src="temp.js"></script> -->
<script type="text/javascript">
(function() {
var e = document.createElement('script');
e.src = 'temp.js';
e.async = true;
document.getElementsByTagName("head")[0].appendChild(e);
})();
</script>
<script type="text/javascript">
console.log('Page Loaded');
</script>
</body>
</html>
答案 0 :(得分:4)
会发生什么
<script>
块1,并将新脚本标记添加到<head>
<script>
块2并加载日志页面<script>
head in head并运行阻塞睡眠功能<head>
块已完成解析并呈现<body>
更改
document.getElementsByTagName("head")[0].appendChild(e);
要
document.getElementsByTagName("body")[0].appendChild(e);
HTML页面将首先加载。
问题是 <head>
中的所有脚本都必须在呈现HTML正文之前加载并运行
答案 1 :(得分:2)
我不知道async
在浏览器中的支持或行为是什么,但我怀疑主要问题在于您的sleep
功能。
通常,睡眠功能将完全按照其说法执行操作 - 暂停当前正在执行的线程并在x
秒内再次唤醒它。你的睡眠功能正在做任何事情 - 它正在执行while循环条件(now + ms) > ((new Date()).getTime ())
和浏览器一样多次。这肯定会锁定任何其他Javascript执行,并且取决于浏览器可能会影响页面呈现。
您想使用setTimeout
在Javascript中模拟睡眠:
setTimeout(function() {
console.log ('Script Loaded');
}, 3000);