5

我正在尝试使用 write 方法和 onload 事件。这是我的代码:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body onload="document.write('body loaded!')">
        <h1>Hello World!</h1>
        <img onload="document.write('img loadeld!')" src="smiley.gif" alt="Smiley face" width="42" height="42" />
    </body>
</html>

如果我在浏览器中运行它,它会输出“img loadeld”并且只是“挂起”,似乎正在无限加载页面。我希望浏览器输出“img loadeld”,然后当 body 元素准备好“body loaded”并正常停止时。

我的问题:

  1. 为什么会有这样的悬念?为什么 img 元素上的 onload 事件会阻止浏览器继续并呈现“已加载正文”?
  2. 为什么如果我从 img 元素中删除 onload 处理程序,响应是预期的 - “加载正文”并且页面没有被阻止。
4

5 回答 5

3

简单地说,在 DOM 准备好document.write() 之后调用会导致它覆盖现有的 DOM。

于 2012-09-11T18:56:42.467 回答
3

一切都正常工作(尽管不像你预期的那样),没有什么是“挂起”或“阻塞”的。然而,这一切发生得如此之快,以至于它看起来并不像这样。希望对写入文档的工作原理和事件顺序的解释将对您有所帮助:

您的 IMG onload 事件在文档关闭后触发(文档准备就绪)。

document.write()但是,只能输出到打开的文档。

如果文档已关闭,则document.write()( docs ) 隐式调用document.open()( docs ) 擦除整个文档。然后,您的呼叫会write输出您告诉它的内容。文档保持打开状态,直到显式关闭(document.close()( docs )),因此“加载微调器”继续显示。

那么,正在发生的基本操作流程(如此之快以至于你没有注意到这一切都在发生并且事情看起来很糟糕)是:

  1. 发出页面请求
  2. 收到页面响应
  3. document被打开,内容被解析并放置到位,包括第一个document.write(不必调用open,因为document当前是打开的)
  4. 文件关闭
  5. IMG 标记的检索完成并触发事件
  6. 事件处理程序调用document.write
  7. 文档被隐式重新打开(新文档创建,所有内容丢失;显示加载微调器)
  8. 你的论点document.write()被输出到新文档中
  9. 一切都完成了,文档仍然打开

应该使用DOM 操作技术(appendChild()、写入innerHTML等)而不是document.write为了修改现有内容而不覆盖所有内容。

消息是,既然发生了这种情况,您确实知道您的图像正在成功加载。你只需要找出正确的方法来应对它,就像我之前逃避的那样。

于 2012-09-11T18:58:47.623 回答
0

document.write加载 html 后在函数内部使用时,它会写入新的html 文档。onload 是一个事件处理程序,所以<img onload="document.write('img loadeld!')"/>= img.onload = function(event){document.write('img loadeld!');}
它不会阻止页面加载,它只会创建新的空白 html 文档。

于 2012-09-11T18:56:14.823 回答
0

那是因为document.write()清除整个文档,然后将参数写入页面,尝试document.writeln('Img loaded');附加到正文,但要坚持你真正想要的:

<img onload="document.body.innerHTML += '<h1>Loaded</h1>'"'

或者编写一个创建元素并使用的函数document.body.appendChild(elem),在这种情况下,您可以document.body用任何块元素替换

于 2012-09-11T18:56:34.473 回答
0

创建一个消息容器,例如 DIV 并设置innerHTML,不要使用 .write()

于 2012-09-11T18:56:36.693 回答