关于javascript:为什么DOM appendChild()会在on(‘load’,…)上触发,而jQuery append()不会呢?

Why does DOM appendChild() fire on('load', …) but jQuery append() does not?

我有以下代码片段:

1
2
3
4
5
6
7
$(document).ready(function() {
    document.head.appendChild(
        $('<script />').attr('src', 'source.js').on('load', function() {
            ...
        })[0]
    );
});

这将触发负载处理程序。

而使用普通的jQuery append()

1
2
3
4
5
6
7
$(document).ready(function() {
   $('head').append(
        $('<script />').attr('src', 'source.js').on('load', function() {
            ...
        })
    );
});

这不会触发负载处理程序。

我缺少什么:为什么jQuery append()无法正常工作?

使用document.head.appendChild()是个坏主意吗?

注意:我不能使用$.getScript()。 该代码将在本地文件系统上运行,Chrome会抛出跨站点脚本错误。

更新资料

某些人在阅读紧凑样式时遇到了麻烦,因此我使用了额外的换行符来澄清哪些对象在调用哪些方法。 我还明确指出我的代码在$(document).ready块内。

最后我去了:

1
2
3
4
5
6
7
$(document).ready(function() {
    $('head')[0].appendChild(
        $('<script />').attr('src', 'source.js').on('load', function() {
            …
        })[0]
    );
});

我认为@istos是对的,因为domManip中的某些内容破坏了load


jQuery的DOM操作代码正在做一些有趣的事情。如果您查看jQuery的源代码,您会发现它在append()方法内部使用了称为domManip()的方法。

domManip()方法创建一个文档片段(看起来该节点首先附加到"安全"片段上),并且具有许多有关脚本的检查和条件。我不确定为什么它使用文档片段,或者为什么存在所有有关脚本的检查,但是使用本机appendChild()而不是jQuery的append()方法会成功触发该事件。这是代码:

实时JSBin:http://jsbin.com/qubuyariba/1/edit

1
2
3
4
5
6
7
8
9
10
11
  var url = 'http://d3js.org/d3.v3.min.js';  
  var s = document.createElement('script');
  s.src = url;
  s.async = true;

  $(s).on('load', function(e) {
    console.log(!!window.d3); // d3 exists
    $(document.body).append('Load fired!');
  });

  $('head').get(0).appendChild(s);

更新:

appendChild()是一种受良好支持的方法,在这种情况下绝对没有理由不使用它。


您不必完全抛弃jquery,可以使用zeptojs。其次,我无法确定这种行为的发生方式和原因。即使我觉得可以在下面的链接中找到答案。到目前为止,我可以告诉您,如果您在definig src元素之前插入元素,则加载不会触发。

但是,对于手动插入而言,这并不重要。 (????)

但是,我能够发现的是,如果您使用appendTo,它将起作用。
代码:http://jsfiddle.net/techsin/tngxnkk7/

1
var $ele = $('<script />').attr('src', link).load(function(){ abc(); }) ).appendTo('head');

新信息:据了解,将脚本标签添加到具有src属性的dom,将启动src中提到的脚本的下载过程。手动插入会导致页面加载外部脚本,使用appendappendTo会导致jquery启动外部js文件的下载。但是使用jquery附加了事件,并且jquery启动了下载,因此事件不会触发。但是,如果是页面本身启动下载,那么它将启动下载。即使没有jquery手动添加事件,通过jquery向dom添加也不会触发它。

我认为应该是答案的链接...

附加vs附加子JQuery

http://www.blog.highub.com/javascript/decoding-jquery-dommanip-dom-manipulation/

http://www.blog.highub.com/javascript/decoding-jquery-dommanip-dom-manipulation/

https://github.com/jquery/jquery/blob/master/src/manipulation.js#L477-523

http://ejohn.org/blog/dom-documentfragments/