示例代码中为什么LI元素是while循环结束后统一追加而非每次循环追加?
问题原因
这是浏览器事件循环机制 + JS线程与渲染线程互斥的特性导致的,具体逻辑如下:
- 浏览器中JS执行线程和页面渲染线程是互斥的,同一时间只能有一个线程在运行,渲染线程的重排/重绘操作必须等待当前JS执行任务完全结束后才能被调度。
- 你当前运行的整段
<script>标签内的代码属于同一个同步宏任务,prompt虽然会暂停JS线程的执行,但不会结束当前宏任务:每次你确认prompt输入后,JS线程恢复执行ul.append(li)修改DOM树,但随后立即进入下一次prompt阻塞,当前宏任务始终没有执行完毕,渲染线程永远拿不到执行权限,DOM的变化自然不会被绘制到页面上。 - 只有当你输入为空触发
break跳出循环,整段script代码执行完成,当前宏任务结束后,浏览器才会调度渲染线程执行,把之前所有DOM修改一次性渲染到页面上。
实现逐次渲染的修改方案
如果想要每次输入后立即渲染li,可以把下一次prompt的触发放到下一个宏任务中,给渲染线程留出执行窗口,示例修改代码如下:
<!DOCTYPE HTML> <html> <body> <script> let ul = document.createElement('ul'); document.body.append(ul); function addListItem() { let data = prompt("Enter the text for the list item", ""); if (!data) return; let li = document.createElement('li'); li.textContent = data; ul.append(li); // 把下一次输入放到下一个宏任务队列,优先执行渲染 setTimeout(addListItem, 0); } addListItem(); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Hongyuan
相关产品推荐
相关产品推荐

