javascript - 使用 document.write() 和 setTimeout() 显示时间

标签 javascript html google-chrome internet-explorer-11 document.write

所以,我正在阅读 MSDN 上的一篇文章 here关于使用 JavaScript 将文本显示到网页的多种方式。但是,我发现最后一个示例非常令人困惑,因为文章中描述的示例行为以及 IE11 中展示的行为与 Chrome 中显示的行为不匹配。

例子如下:

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[StackOverlow document.write() question]">
<script type="text/javascript">
    function ShowTime()
    {
        var dt = new Date();
        document.write(dt.toTimeString());
        // var elem = document.getElementById("divElem");
        // elem.textContent = dt.toTimeString();
        window.setTimeout("ShowTime();", 5000);
    }
</script>
</head>

<body>
<script type="text/javascript">
    ShowTime();
</script>
<div id="myDiv"></div>
</body>
</html>

该代码被描述为只显示两次时间,中间间隔 5 秒。这对于 IE11 是正确的。明确地说,这就是正在发生的事情:

  1. 时间立即显示
  2. 等待 5 秒
  3. 显示的时间更新为当前时间

但是,如果我在 Chrome 中运行该示例,它运行如下:

  1. 时间立即显示
  2. 等待 5 秒
  3. 显示的时间更新为当前时间
  4. 等待 5 秒
  5. 在已经显示的内容旁边显示一个单独的时间戳
  6. 无限期地重复第 4 步和第 5 步...

任何人都可以通过解释每个浏览器使用 document.write() 和 setTimeout() 背后的机制来详细说明为什么代码会以这种方式运行吗?

非常感谢任何帮助。提前致谢!

最佳答案

首先,您不应该使用 document.write()。早期它是在 DOM 中编写内容的唯一方法,但今天它应该只被使用……好吧,实际上它不应该被使用。曾经。如果他们弃用并完全删除它,我会很高兴。

每个元素都被添加到 DOM 中,脚本按照接收到的顺序(从上到下)执行。所以header中的script标签先被执行。因为它只有一个函数,所以什么都不会执行。它只是将 ShowTime 函数存储在内存中以供其他时间使用。

然后它继续加载 DOM 的其余部分,直到它到达第二个脚本标记。它也执行它。该标签调用 ShowTime 所以指针跳转到 ShowTime 函数并从上到下执行它(这就是为什么我将第二个脚本移动到 myDiv div 标签之后,在该标签存在之前执行它意味着它还没有被添加到 DOM并且 document.getElementById 将返回一个空值,这意味着 elem.textContent = ... 将停止并出现错误,提示 elem 不是对象并且不包含textContent 属性)。

setTimeout 将函数的执行延迟一次。但是,由于 setTimeout 在函数内,它本质上是“无限循环”。一旦函数被调用一次,它将运行并将时间设置到 ID 为“myDiv”的 div 中,然后将调用 setTimeout 函数再次调用自身。因此,5 秒后它再次调用自身,然后再设置另一个超时 5 秒。然后再次执行自身并再次设置另一个超时 5 秒......你会看到这里发生的模式。每个浏览器应该没有区别。他们都应该以同样的方式处理这个问题。

所以...使用注释代码应该可以正常工作(并且是写入 DOM 元素的公认方式):

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[StackOverlow document.write() question]">
<script type="text/javascript">
    function ShowTime()
    {
        var dt = new Date();
        var elem = document.getElementById("myDiv");
        elem.textContent = dt.toTimeString();
        window.setTimeout("ShowTime();", 5000);
    }
</script>
</head>

<body>
<div id="myDiv"></div>
<script type="text/javascript">
    ShowTime();
</script>
</body>
</html>

所以回到 document.write。为什么它在每个浏览器中的行为不同?根据the standard , document.write() 应该只写入一个新文档。如果文档已经存在(例如,你有脚本的页面),它应该首先执行一个 document.open() ,这将清除页面的所有内容并开始一个新的空白文档。为什么 Chrome 不清除?我不知道。开发人员可能没有更新该功能,因为不建议再使用它。我进行了搜索,但没有想出任何关于 Chrome 的行为为何会有所不同的原因。我在一个站点上对其进行了测试,该站点已为我清除,因此您可能使用的是可能存在错误的旧版 Chrome?不幸的是,我无法提供更好的解释,但我绝对认为您应该注意警告并避免完全使用 document.write

关于javascript - 使用 document.write() 和 setTimeout() 显示时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341795/

相关文章:

javascript - JS在点击一个div时应用自定义样式并从另一个div中删除样式

javascript - 运行存储在字符串变量中的 Javascript 函数

javascript - 无法使用 d3.js 在 html 中加载 json 文件

html - 在连续流上解码音频数据失败并出现空错误

java - 无法使用 Selenium Webdriver java 在 Linux 机器上运行 Headless Chrome 浏览器

javascript - chrome devtools 调试 react ,命中 "refresh"导致调试卡住

javascript - RegEx 用原生 JS 分割查询字符串

javascript - 将 mysql 脚本转换为 sqlite 脚本

css - 如何在带边框的动态高度内容区域内正确显示两个并排的 div?

javascript - 使用 JavaScript 的数组中的两个下拉值