我希望for循环在迭代过程中更新<li>
个项目,而不是。之后。
这是完整的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="for">
<ul id="unordered-list">
</ul>
</div>
<script>
const parentUL = document.querySelector('#unordered-list');
for (let i = 0; i < 100000; i++) {
const li = document.createElement('li');
li.innerHTML = i;
parentUL.appendChild(li);
}</script>
</body>
</html>
我希望<li>
将在for循环运行时进行更新,在当前情况下,所有这些都将在循环运行完成后出现。
答案 0 :(得分:0)
这里出现的“问题”是ECMAscript是单线程进程。在大多数情况下,ECMAscript代码在称为“ UI线程”的内部运行。正如您可能已经猜到的那样,其他过程(例如更新和可视化DOM组件(包括CSS更改))也正在此过程中运行。 现在,无需赘述,这里发生的事情基本上是这样的:
[ HTML:DOM Rendered - UI UPDATE - JS:LOOP(100000) - UI UPDATE ]
由于整个循环是同步运行的,因此UI线程没有机会显示任何渲染的更新。实现此目标的唯一机会是不时手动中断循环。
有几种方法可以做到这一点,最简单的方法就是使用setTimeout()
。
您可以将代码重新编写为:
let i = 0;
(function loop() {
const li = document.createElement('li');
li.innerHTML = i++;
parentUL.appendChild(li);
if( i < 100000 ) {
setTimeout(loop, 20);
}
}());
现在发生的是,您的JS代码的执行每20毫秒中断一次,并且UI线程可以更新任何必要的可视更改。
[ HTML:DOM Rendered - UI UPDATE - loop() - UI UPDATE - loop() - UI UPDATE - ... ]
答案 1 :(得分:0)
尽管100000是一个很高的数字,例如for / loop不需要花费更长的时间(几毫秒)。而且由于具有更好的性能和用户体验,浏览器可以优化此类更改的刷新率。如果您希望每个附加项之间都有明显的时差,则可以这样添加超时:
const parentUL = document.querySelector('#unordered-list');
for (let i = 0; i < 100000; i++) {
const li = document.createElement('li');
li.innerHTML = i;
setTimeout(()=>{
parentUL.appendChild(li);},i * 250);
})
}