window.setTimeout在Firefox 18和IE10中不工作(Chrome和Safari可以工作)



我有这个示例代码:

<!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.write更改为console.log,那么它适用于所有浏览器。为什么?

这是Chrome和Safari(或者更准确地说是WebKit)中的一个错误。当页面未处于解析中期时,document.write意味着document.open,而document.open应该根据规范清除所有超时。IE和Firefox就是这样做的,但WebKit对document.open的处理有点糟糕。

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

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

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

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

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

一般来说,document.write是一种非常糟糕的做法。它非常慢,因为解析器必须为每种HTML元素解析给定的字符串。请改用document.createTextNodedocument.createElement

相关内容

  • 没有找到相关文章

最新更新