Summary


1. Chrome、Safari、Firefox、Opera 下,script 添加到 fragment 中时不会下载,添加
   到 DOM 树中时才会下载并执行,并且执行上下文是全局环境,一切符合预期。

2. IE6-9 下,在 script 设置 src 属性时就会触发下载,添加到 fragment 或其他 DOM 节点
   时会触发执行。执行时上下文是 fragment,相当于

       with(fragment) { (function() { script code }).call(fragment) }

   当有缓存时,情况更复杂,详见参考文档 [3]

3. 标准浏览器包括 IE9+ 下,fragment 没有 createElement 等方法,但在 IE6-8 下有。

4. IE10 与 Chrome 等标准浏览器表现一致,赞。


本来想利用 DocumentFragment 来解决 IE6-9 下获取 script 的 src 的问题,比如:

    fragment['define'] = function(require, exports, module) {
      // 很自然地得到了模块 id
      module.id = script.src

      // 调用 seajs 的 define
      window.define(require, exports, module)
    }

现在看起来带来的隐患很多。如果用 DocumentFragment 来动态插入 script,则 script code
在执行时,相当于

       with(fragment) { (function() { script code }).call(fragment) }

   a) script code 执行时多了一层闭包,这导致 var xx = ... 不再是全局变量。
   b) script code 执行时的 this 是 fragment,不是 window,这会带来很多问题。
   c) 多了一层闭包,如果 script code 代码不当,会导致内存泄露。

这样,利用 DocumentFragment 来动态插入 script,只适合纯数据的 JSONP,比如

   define({
     "a": "a",
     ...
   })

上面这种情况下,利用 DocumentFragment 来实现 JSONP,简单方便,并能提升性能。


补充:不用 DocumentFragment 做容器,用普通 div 元素做容器,IE6-9 下会自动创建一个匿名
     document,执行时变成

       with(document) { (function() { script code }).call(document) }

     问题依旧。


最后更新时间:2012-12-17


参考文档:

  - https://developer.mozilla.org/en-US/docs/DOM/document.createDocumentFragment
  - http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/
  - http://www.guypo.com/technical/ies-premature-execution-problem/
  - http://velocity.oreilly.com.cn/2012/ppts/xuxiao.pdf
  - http://varnow.org/?p=152
  - http://www.cnblogs.com/objectorl/archive/2009/08/05/1632718.html
  - http://www.cnblogs.com/rubylouvre/archive/2012/12/16/2820372.html
  - http://www.webshowme.com/04js/content.asp?id=1613