关于 document.write 方法请参考标准文档:DOM Level 2 HTML 规范 1.5. Objects related to HTML documents。
当脚本中存在以 document.write 的方式向页面内写入内容时,各浏览器对于执行各个线程的顺序可能不一致。
此现象造成在各浏览器里,某些需要延后执行的代码被立即执行,导致程序出错。
IE6 IE7 IE8 |
---|
由于 W3C DOM 标准文档中,没有明确说明使用 document.write 方法外引 JS 文件后,被引用脚本文件内继续重复使用 document.write 引用其他外部脚本文件时的执行顺序问题,因而导致实际环境中各个浏览器具体实现不一。
我们来分析以下代码 A:
<script> document.write("before write h1.js"+"<br/>"); document.write("<script src='h" + "1.js'><\/script>"); document.write("after write h1.js" +"<br/>"); </script>
/* h1.js */ document.write("This is h1.js"+"<br/>");
即在一个 SCRIPT 标签内,通过 document.write 的方式向文档输入内容,并在其间引入 JS 文件 A,A 内也包含 document.write,意在向文档输出某些内容。
各浏览器表现如下:
IE6 IE7 IE8 | Firefox Chrome Safari Opera | |
---|---|---|
执行输出顺序 |
before write h1.js
after write h1.js This is h1.js |
before write h1.js
This is h1.js after write h1.js |
即 IE 是在当前 SCRIPT 标记内所有的 document.write 向文档中输出内容完成后,再处理以 document.write 方式引入的 JS 文件内的 document.write 写入流。
对于其他浏览器,则根据代码执行顺序依次处理 document.write 方式写入的内容。
此外,使用 document.write 方式写入可引用的外部 JavaScript 内容后,非 IE Opera 浏览器并不会立即更新 DOM 树。
分析以下代码 B:
<script> document.write('<script src="a.js"><\/script>'); document.write('<DIV id="d1"></DIV>'); alert(document.getElementById('d1')===null); </script>
/* a.js */ //可以不包含代码
示例脚本通过 document.write 的方式向文档输入其他的 SCRIPT 标记引入其他 JS 文件以及其他内容。立即写入一个 DIV 标记后通过 getElementById 方法得到该元素的 DOM
引用。
各浏览器表现如下:
IE6 IE7 IE8 Opera | Firefox Chrome Safari |
---|---|
false | true |
对于以上测试代码,IE Opera 表现为在执行到语句 "document.write('<DIV id="d1"></DIV>');" 后立即更新了文档的 DOM 结构(向文档内插入了 ID 为 d1 的 DIV 标记)。
而在其他浏览器里,在当前 SCRIPT 标记的执行流运行完成后,才更新文档的 DOM 结构。
此外,还存在另外问题,分析以下代码 C :
<script> document.write('<script id="d1" src="a.js"><\/script>'); document.write('<script id="d2"></scirpt>'); alert([document.getElementById('d1'),document.getElementById('d2')); </script>
/* a.js */ //可以不包含代码
各浏览器表现如下:
IE6 IE7 IE8 Opera | Firefox Chrome Safari |
---|---|
[Element, Element] | [Element, null] |
本例中,Firefox Safari Chrome 浏览器下,id="d2" 的 Script 元素将输出 null。 除非 d1 不是加载外部资源,d2 元素才可能会立即被获取到;或者同上例一般,在当前脚本块执行流完后才可以访问到 d2、这个问题原因不明,Firefox Safari Chrome 这些浏览器可能因为脚本元素 d1 的外部资源加载而导致 d2 元素没有被及时放入 DOM Tree。
如果外部引用的 JS 文件内程序,要求在执行顺序上一致,请避免使用 document.write 语句引入的 JS 程序文件中再次使用他来加载外部 JS 文件。
可以参考 动态引入的外部 JS 文件在各浏览器中的执行顺序不一致 文章内解决方案。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6 Chrome 4.0.302.3 dev Safari 4.0.4 |
测试页面: |
document_write_js_file.html
dom_tree_update.html |
本文更新时间: | 2010-08-06 |
documen.wirte SCRIPT 延迟执行 DOM 树更新