有没有一种方法可以从for循环中更新DOM元素?

时间:2019-03-25 22:57:54

标签: javascript

我希望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循环运行时进行更新,在当前情况下,所有这些都将在循环运行完成后出现。

2 个答案:

答案 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);
        })
    }
相关问题