为什么这个setInterval / document.write代码在Chrome上运行但在Firefox上不运行?

时间:2016-01-20 15:05:29

标签: javascript google-chrome firefox

这是一个简单的程序,可以在浏览器窗口中打印数字1到10。



var t = 1;
var a = function timer() {
  if (t < 11) {
    document.write(t + "<br/>");
    t = t + 1;
  } else {
    clearInterval(handle);
  }
}
var handle = setInterval(a, 100);
&#13;
&#13;
&#13;

这适用于Chrome(数字1到10之间会有短暂的延迟),但不适用于Firefox(只显示1,没有错误)。为什么呢?

我知道我可以使用console.log,但这不是重点。为什么document.write在Chrome和Firefox之间有不同的工作方式?

2 个答案:

答案 0 :(得分:4)

这是 Chrome WebKit中的错误;根据{{​​3}},它也发生在Safari上。

在页面主要解析完成后调用Kaiido涉及对document.open的隐式调用。 document.write,调用document.open应该销毁文档,删除所有事件处理程序,并丢弃所有任务。这意味着Firefox正在做的是正确的,因为它在空白文档中显示1。它不会继续运行,因为setInterval安排的任务已被丢弃。

正如您所指出的那样,有时候Firefox浏览器会继续前进,就像它期待其他事情发生一样。我喜欢According to the specification关于为什么这样做:当我们执行document.write(1)时,我们隐含地执行了document.open,并且它正在等待document.close。事实上,如果我们在您的代码中添加document.close来测试它,那么微调器就不会停留在:

var t = 1;
var a = function timer() {
  if (t < 11) {
    document.write(t + "<br/>");
    t = t + 1;
    document.close(); // Just to test Firefox's spinner
  } else {
    clearInterval(handle);
  }
}
var handle = setInterval(a, 100);

答案 1 :(得分:0)

除了T.J.的观点。关于webkit错误的杂烩,考虑这两个脚本以及为什么你的代码没有像你预期的那样工作。

脚本1

<html>
<head>
    <title>foo</title>
    <script>    
    t = 1;
    var a = function timer() {
        if (t < 11) {
            document.write(t + "<br/>");

            t = t + 1;
        }

    }
    setInterval(a, 100);
</script>
</head>
<body>
    <script>
        alert('page fully loaded')
    </script>
</body>
</html>

脚本2

<html>
<head>
    <title>foo</title>
    <script>  
    for(var i = 1; i < 11; i++) { 
        document.write(i + "<br />");
    }
</script>
</head>
<body>
    <script>
        alert('page fully loaded')
    </script>
</body>
</html>

结果

脚本1

在第一个页面关闭后,setInterval()再次触发 。您将看到警告消息,指示页面已完全执行,文档已关闭以进行写入。发生 之后,您将看到第一个间隔触发document.write。这将卸载以前关闭的旧文档,并仅向页面添加1<br />

由于旧文档已被卸载,现有的javascript已经消失,除了第一次迭代之外没有其他任何内容可以执行。

脚本2

在第二个脚本中,document.write在当前文档仍处于打开状态时执行多次。由于{<1}}函数在文档自然关闭之前执行,因此文档的原始内容永远不会被覆盖。

结论

直接与DOM元素交互比使用document.write更好。

这里有一些更好的阅读:https://pigeoto.wordpress.com/2011/01/19/why-doesnt-document-write-work-with-setinterval/