检查body标记时出现意外的JavaScript无限循环

检查body标记时出现意外的JavaScript无限循环,javascript,infinite-loop,preloader,document-body,Javascript,Infinite Loop,Preloader,Document Body,我打算尽快编写脚本,检查是否加载了body标签,但这会导致整个页面冻结 这是: while (!document.body) if (document.body) console.log('loaded'); 当然,这并不是在所有情况下都能正常工作,但我不明白为什么这会变成一个无限循环并冻结页面。Javascript是单线程的。当循环运行时,其他任何东西都不会运行,因此无法加载实体。循环体中没有任何内容会更改document.body的值,因此,如果在开始时未设置该值,则永远不会设置该

我打算尽快编写脚本,检查是否加载了body标签,但这会导致整个页面冻结

这是:

while (!document.body)
    if (document.body) console.log('loaded');

当然,这并不是在所有情况下都能正常工作,但我不明白为什么这会变成一个无限循环并冻结页面。

Javascript是单线程的。当循环运行时,其他任何东西都不会运行,因此无法加载实体。循环体中没有任何内容会更改document.body的值,因此,如果在开始时未设置该值,则永远不会设置该值。

此代码同步执行,因此,如果document.body最初未定义,则不允许浏览器在迭代之间填充它。使用setTimeout或setImmediate来实现这一点,或者更好的方法是侦听事件或使用jQuery的


我不明白为什么这会变成一个无限循环并冻结页面。-因为它是一个无限循环?当JS同步执行时,DOM解析器暂停。您需要使用事件。你不能用循环来实现这一点。如果你想要一个简单的javascript函数来告诉你DOM何时准备好了,请看这里:我不认为这个问题是由于JS的单线程性,而是因为浏览器UI的单线程性。因此,这取决于脚本包含在哪里。如果它在身体标签之前运行,那么它应该是好的,然后,我认为它们是一样的。页面中的所有内容都有效地在一个线程中运行。@feat.martin将其放在后面是完全多余的。while循环的主体将永远不会被输入。@feat.martin他显然试图在加载文档之前做一些事情,可能是某种进步。是的,这是我之前评论的第二个解决方案,考虑到这一点:。为什么不先在头部打开一个脚本标记,在身体加载之前开始做任何你想做的事情,然后在身体加载之后伪造这个条件呢?我很难看出你的动机,但是,通常的做法是在DOM可用时倾听,正如@Klaus所说。@feat.martin这就是他在问题中尝试的。他启动了一个while循环,并期望在装载尸体时情况会发生变化。问题是脚本运行时无法加载主体。这就是为什么这个setTimeout是必要的——它允许脚本定期退出并重新启动,以允许主体加载。
(function ready() {
  if (document.body) console.log('loaded');
  else setTimeout(ready, 500); // delay 1/2 second
})();