IE Bug:DocumentFragment和SCRIPT

>
最近在学习如何利用动态加载javascript文件的技术来提高页面的加载速度。实践中了解到,在浏览器解析并呈现(Render)HTML文档的过程中,一旦遇到带有src属性script标记,浏览器会立即阻断页面的呈现,并立即去寻找和加载javascript外部文件。如果文件尺寸很大,则会使页面出现空白状态,在降低页面呈现速度的同时也带给用户很糟糕的体验。
Nicholas C. Zakas在他的个人博客中对这一问题提供了很好的解决方案。原理其实很简单,即在HTML文档流中仅加载一个尺寸较小的javascript外部文件,同时我们把其余的javascript代码存储为一个尺寸较大的外部文件。我们在那个尺寸较小的文件中我们编写一段代码,该代码利用DOM动态地向HTML Document中插入script节点以加载尺寸较大的那个外部文件。就这么简单!关于该解决方案的详细探讨,请参考Zakas的文章
The Best Way to load external JavaScript .
好了,言归正传,现在来说说IE在此处的一个bug吧~我当时写了一个测试脚本来测试如何动态加载js外部文件,该脚本首先创建一个文档碎片(Document Fragment)对象:
var fragment = document.createDocumentFragment();
然后创建了一个script节点,该节点就是要引用大尺寸js外部文件的节点,代码如下:

var script = document.createElement('script');
script.type='text/javascript';
script.src='script.js';

为了测试方便,外部文件script.js文件中只定义一个myObject对象,script.js文件内容如下:
/* content of script.js */
var
myObject = new Object;
关键的地方在这里,然后我将script节点插入到文档碎片中,最后将文档碎片插入到document.body中,代码如下:
fragment.appendChild(script); /* IE will generate bug here */
document.body.appendChild(fragment); /* insert fragment into HTML document */
在这里,火狐及其他非IE内核浏览器在此处运行非常完美,但是IE会产生一个致命的问题:利用文档片段的方式向HTML文档插入script标记,在IE中这个script节点会成功地插入到文档中,但是script节点所引用的外部文件中的任何代码都不会被IE执行!!我们可以用下面的代码进行测试:

window.onload = function() {
    alert
(typeof myObject);
} ;

Firefox等非IE浏览器会正确显示object,但是IE却显示undefined.显然IE并没有执行这个外部文件中的任何一行代码。
解决问题的方式也简单:为了兼容和“照顾”,IE我们索性直接将我们新建的script节点插入到HTML文档(document.body)中:
document.body.appendChild(script);
这样,无论是IE还是火狐运行都是正常的。

题外话:为什么我要使用文档碎片?
假如我们要动态加载不只一个外部js文件呢?我们会将这些外部文件以script节点的形式一个一个地插入的HTML文档中吗?我肯定不会这样做,因为这增加了对HTML文档的修改次数,无形中增加了浏览器的负担,也是我们的代码运行速度更慢。
而使用文档碎片的方法则不然,因为这种方法是在内存中新建一块文档块,然后将我们的节点直接在内存中插入到文档碎片中,最后一次性将该文档碎片插入到HTML文档中,一共对文档进行了仅一次的修改,加快了代码的运行速度。

posted @ 2009-08-05 23:29  eliuhy  阅读(769)  评论(0编辑  收藏  举报