9

当我在 Chrome(版本 2)中运行它时,它不会返回字符串,但它可以在 Firefox(版本 3)中运行。为什么是这样?

<html>
<head>
<script type="text/javascript">
function disp_prompt() {
    var name=prompt("Please enter your name","Harry Potter");
    if (name!=null && name!="") {
        document.write("Hello " + name + "! How are you today?");
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>
4

4 回答 4

32

要将内容附加到文档,您应该只document.write()在 <script>-block 解析阶段调用。

如果您调用了document.write它在该上下文之外执行的某个地方,例如在您的事件处理程序中,则不会进行解析,因此该字符串无处'foo'可去。

根据原始 JavaScript 参考应该发生的是:

事件处理程序在原始文档关闭后执行,因此如果您没有在事件处理程序中显式发出 document.open 方法,则 write 方法会隐式打开 mimeType text/html 的新文档。

也就是说,它假设您犯了一个错误并且打算这样做:

document.open('text/html');
document.write(html);

它将整个文档替换为新内容。您还会注意到,因为您没有通过调用完成该操作:

document.close();

...在 Firefox 中,“正在加载”的 throbber 仍然处于动画状态,期望将更多内容写入文档(但它永远不会出现)。

在这种情况下,您正在document.write()输入一个字符串:

Hello bobince! How are you today?

这显然不是一个有效的 HTML 文档。Chrome(和 Safari,行为相同)试图将其解析为 HTML 文档,但由于它是文档元素 (<html>) 之外的非空白文本内容而失败,这是不允许的。如果您在名称输入中放置一些标签:

Hello <em>bobince</em>! How are you today?

你会看到 <em> 元素之外的所有东西都被丢弃了。Firefox 和 IE 设法应用他们的“修复任何元素之外的文本”损坏的 HTML 规则来拯救你,但 Chrome 没有。

如果你想要document.write()一个新文件,你应该确保它确实是一个完整的文件:

<html><head><title>Greetings</title><body><p>Hello bobince! How are you today?</p></body></html>

或者,如果你想要document.write()一个文本字符串,理论上你应该调用:

document.open('text/plain');

在 write() 之前。但请注意,Chrome 或 Safari 不支持 mimetype 参数;他们将始终将您编写的内容视为 HTML。

无论如何,您可能不想使用这种方法。如果您想添加(或更改)现有页面,您通常应该使用 DOM 方法,例如在状态输出 div 上设置文本,或使用 innerHTML 替换正文内容。

document.write()在一些地方需要(特别是当您从头开始创建新窗口或框架时),但否则通常是错误的,应该怀疑。

于 2009-04-18T02:56:00.827 回答
9

不要使用 document.write。如果你把它改成类似

if (name != null && name != "") {
    document.getElementById('foo').innerHTML = "Hello " + name + "! How are you today?";
}

<body>
<input ...

<div id='foo'> </div>
</body>

document.write 有很奇怪的行为。您希望将文本写入哪里?

于 2009-04-17T22:26:21.893 回答
2

只需在 write 调用中添加一些段落标签:

<html>
<head>
<script type="text/javascript">

function disp_prompt() {
    var name = window.prompt("Please enter your name", "Harry Potter");
    if (name) {
        window.document.write("<p>Hello " + name + "! How are you today?<\/p>");
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>
于 2009-04-17T23:37:14.533 回答
0

参加聚会有点晚了,但我document.write()在 Chrome DevTools 中看到了一个带有链接的违规行为。不用说,这是一本有趣的书。

这是关于什么的?

document.write()从 Chrome v55 开始,Chrome 将在一组非常选择的情况下开始阻止。你可以在这里读到它:

https://developers.google.com/web/updates/2016/08/removing-document-write

这应该对使用 2G 蜂窝连接的用户以及可能其他类型的连接速度较慢的用户生效。以下是相关文章的摘录:

考虑到这些数据,Chrome 从版本 55 开始,当我们通过更改 Chrome 中处理 document.write() 的方式检测到这种已知的不良模式时,Chrome 会代表所有用户进行干预(请参阅 Chrome 状态)。具体来说,当满足以下所有条件时,Chrome 将不会执行通过 document.write() 注入的元素:

  1. 用户的连接速度很慢,特别是当用户使用 2G 时。(将来,这种变化可能会扩展到其他连接速度较慢的用户,例如慢速 3G 或慢速 WiFi。)
  2. document.write() 位于顶级文档中。干预不适用于 iframe 中的 document.written 脚本,因为它们不会阻止主页的呈现。
  3. document.write() 中的脚本是解析器阻塞的。具有“异步”或“延迟”属性的脚本仍将执行。
  4. 该脚本未托管在同一站点上。换句话说,Chrome 不会干预具有匹配 eTLD+1 的脚本(例如,在www.example.org上插入的 js.example.org 上托管的脚本)。
  5. 该脚本尚未在浏览器 HTTP 缓存中。缓存中的脚本不会导致网络延迟,仍会执行。
  6. 页面请求不是重新加载。如果用户触发了重新加载,Chrome 将不会进行干预,并将正常执行页面。

第三方片段有时使用 document.write() 来加载脚本。幸运的是,大多数第三方提供了异步加载替代方案,允许第三方脚本加载而不会阻止页面上其余内容的显示。

因此,如果您document.write()满足所有 6 个条件,那么 Chrome 将阻止它。当它发生时,您应该能够在 DevTools 中看到该消息。

OP的问题

要解决 OP 的问题,document.write()必须先使用才能使用document.open("text/html")。完成对文档的写入后,您需要使用document.close(). 如果您只是要编写纯文本,请使用document.open("text/plain"). 但是,我最近在某处读到 Chrome 会忽略 mimetype 并强制使用 text/html。

<html>
<head>
<script type="text/javascript">
function disp_prompt() {
    var name=prompt("Please enter your name","Harry Potter");
    if (name!=null && name!="") {
        document.open("text/plain");
        document.write("Hello " + name + "! How are you today?");
        document.close();
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>

- 或者 -

您可以修改您编写的文本以包含正确的 HTML,如下所示:

document.write('<html><head></head><body>Hello ' + name + '! How are you today?</body></html>');

不要忘记在所有情况下添加document.open()和。document.close()

于 2021-07-16T14:57:41.677 回答