<!DOCTYPE html>
<html>
<head>
</head>
<body>
<ul>
<li>Skittles</li>
<li>Starburst</li>
<li>Twix</li>
</ul>
<script type="text/javascript">
function timeDiff(n){
var start = now = Date.now();
while(now - start < n*1000){
now = Date.now();
}
}
var lis = document.getElementsByTagName("li");
lis[0].textContent = "Text 1";
timeDiff(2);
lis[1].textContent = "Text 2";
timeDiff(2);
lis[2].textContent = "Text 3";
timeDiff(2);
</script>
</body>
</html>
运行上面的代码时,程序将等待6秒钟,然后一起更改所有三个li的文本。
如果我在控制台中运行以下javascript:
console.log("Text 1");
timeDiff(2);
console.log("Text 2");
timeDiff(2);
console.log("Text 3");
timeDiff(2);
然后,控制台将打印“文本1”,等待2秒,然后打印“文本2”,等待2秒,然后打印“文本3”。
为什么两种情况下Javascript的行为都不一样?在第一种情况下,它是一起操纵li的,而在第二种情况下,它是在控制台上一个接一个地打印。
答案 0 :(得分:1)
第一个示例中的代码问题是您正在做的事情称为忙等待。在javascript完成执行后,浏览器会更新页面显示的html。该脚本将在6秒钟后完成执行,这就是您看到列表项更改的时间。如果您希望经过一定时间后在javascript中发生某些事情,则应使用setTimeout
答案 1 :(得分:1)
在JavaScript返回主事件循环之前,浏览器不会将更改呈现给DOM。这样,脚本就可以对页面进行大量更改,并且用户看不到所有中间步骤,而只能看到最终结果。
在控制台中执行语句时,它会在每个语句之后返回到主事件循环,因此您可以看到更改的结果。但是,当您运行脚本时,在整个脚本完成之前不会呈现任何内容。
使用while
来延迟操作,而不是setTimeout
循环。在等待超时完成时,这不会阻止浏览器。
var lis = document.getElementsByTagName("li");
setTimeout(() => {
lis[0].textContent = "Text 1";
setTimeout(() => {
lis[1].textContent = "Text 2";
setTimeout(() => {
lis[2].textContent = "Text 3";
}, 2000);
}, 2000);
}, 2000);
<ul>
<li>Skittles</li>
<li>Starburst</li>
<li>Twix</li>
</ul>