为什么对话框弹窗优先级高于DOM元素,prompt先于document.write执行?
问题原因
这个现象是浏览器的单线程执行机制和document.write、prompt的API特性共同导致的:
- 浏览器的JS执行和页面渲染共享同一个主线程,同一时间只能做一件事,同步JS代码的执行会阻塞页面渲染
document.write写入的内容不会立刻渲染到页面上,会先存入文档缓冲区,等当前所有同步JS代码执行完毕后,才会统一触发渲染流程将内容展示出来prompt是同步阻塞API,调用后会直接暂停主线程的所有后续操作(包括JS执行和页面渲染),直到用户完成弹窗交互才会恢复执行
你给出的代码属于同一段同步执行任务,实际运行流程和预期的差异如下:
- 首先执行
document.write(Hello),内容写入缓冲区,未渲染到页面 - 立即执行
prompt弹出窗口,阻塞主线程,此时渲染流程还未触发,页面是空白状态 - 用户输入姓名后线程恢复,执行第二个
document.write,把拼接后的内容写入缓冲区 - 所有同步代码执行完毕,浏览器才将缓冲区的所有内容一次性渲染出来,才能看到完整的欢迎文本
解决方案
如果要实现「先渲染欢迎内容,再弹出姓名询问框」的效果,只需要把prompt放到异步任务队列,等当前同步任务执行完毕、页面渲染完成后再触发即可,最简单的修改方式是加0延迟的setTimeout:
document.write(`Hello `); setTimeout(() => { const text = prompt(`what's your name?`); document.write(`${text}, nice to meet you :)`); }, 0)
内容的提问来源于stack exchange,提问作者Stairss
相关产品推荐
相关产品推荐

