1

我有这个示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="UTF-8">
  </head>
  <body>
    <script>
      var EventHandler = {};
      EventHandler.writeNumber = function(i){
        document.write(i);
      };      

      for(var i=0; i<100; i++) {
        (function(i) {
          window.setTimeout(function() {
            EventHandler.writeNumber(i);
          },100*i);
        }(i));
      }
    </script>
  </body>
</html>

代码每秒在页面上写入一个数字。在 Chrome 26 和 Safari 5 中运行良好!在 Firefox 18 和 IE10 中它只出现一次(0 写在文档上)。

如果我更改document.writeconsole.log,那么它适用于所有浏览器。这是为什么?

4

2 回答 2

2

这是 Chrome 和 Safari(或更准确地说是 WebKit)中的一个错误。Adocument.write当页面不在中间解析时意味着 a document.open,并且 adocument.open应该清除每个规范的所有超时。这就是 IE 和 Firefox 所做的,但 WebKit 的处理document.open是各种各样的。

于 2013-02-12T14:39:24.720 回答
1

document.write应该只在页面加载时工作一次。

从上到下解析一个页面。解析时找到的每个 JavaScript 都会立即执行。当执行结束或被分派(setTimeout或任何其他异步内容)时,浏览器会继续解析。

当您执行解析器时,将在结束标记之后直接document.write("Test")创建一个文本节点,因为它当前正好在这个位置。如果您将其延迟 1毫秒,则解析器将位于不同的点,在页面下方插入文本节点。Test</script>setTimeout

如果您等待太久,解析器将完成对页面的解析并且不再接受写入。或者,对于 chrome,解析器会尝试修复程序员的错误并保留对标记位置的引用,从而在实际解析完成后<script>仍然可以使用。document.write

使用控制台和 Firebug ( F12) 看看会发生什么。

笼统地说document.write是一种非常糟糕的做法。这非常慢,因为解析器必须为每种 HTML 元素解析给定的字符串。使用document.createTextNodedocument.createElement代替。

于 2013-02-11T21:40:38.830 回答