Javascript 为什么DOM appendChild()会启动(';load';,…),而jQuery append()不会启动?

Javascript 为什么DOM appendChild()会启动(';load';,…),而jQuery append()不会启动?,javascript,jquery,dom,onload,Javascript,Jquery,Dom,Onload,我有以下代码片段: $(document).ready(function() { document.head.appendChild( $('<script />').attr('src', 'source.js').on('load', function() { ... })[0] ); }); 这将不会触发负载搬运器 我缺少什么:为什么jQueryappend()不起作用 使用document.head.a

我有以下代码片段:

$(document).ready(function() {
    document.head.appendChild(
        $('<script />').attr('src', 'source.js').on('load', function() {
            ...
        })[0]
    );
});
这将不会触发负载搬运器

我缺少什么:为什么jQuery
append()
不起作用

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

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


更新

有些人在阅读紧凑样式时遇到困难,所以我使用额外的换行符来澄清哪些对象在哪里调用了哪些方法。我还明确表示,我的代码位于
$(document.ready
块中


解决方案

最后,我选择了:

$(document).ready(function() {
    $('head')[0].appendChild(
        $('<script />').attr('src', 'source.js').on('load', function() {
            …
        })[0]
    );
});
$(文档).ready(函数(){
$('head')[0]。追加子项(
$('').attr('src','source.js')。on('load',function(){
…
})[0]
);
});

我认为@istos是对的,
domManip
中的某些东西正在破坏
load

jQuery在其DOM操作代码中做了一些有趣的事情。如果查看jQuery的源代码,就会发现它在
append()
方法中使用了一个名为
domManip()
的方法

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

实时JSBin:

var url='1〕http://d3js.org/d3.v3.min.js';  
var s=document.createElement('script');
s、 src=url;
s、 异步=真;
$(s).on('load',函数(e){
console.log(!!window.d3);//d3存在
$(document.body).append('Load fired!');
});
$('head').get(0.appendChild);

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

可能问题是当您选择DOM appendChild时,实际上您调用的函数是
document.on('load',function(){})$('head')。在('load',function(){})

文档
标题
不同

您可以键入以下代码:

$(document).find('head').append($('').attr('src','source.js').end().on('load',function()){
...
}));

您可能应该确保在文档准备就绪时启动jquery append。可能是当append启动时head实际上不在dom中。

您不必完全抛弃jquery,您可以使用zeptojs。其次,我无法找出这种行为究竟是如何发生的,以及为什么发生的。尽管我觉得答案可以在下面的链接中找到。到目前为止,我可以告诉你们,若你们在定义src元素之前插入元素,那个么加载就不会启动

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

然而,我发现,如果使用
appendTo
,它是有效的。 代码:

var$ele=$('').attr('src',link).load(function(){abc();})).appendTo('head');
新信息:众所周知,向dom添加带有src属性的脚本标记会启动src中提到的脚本下载过程。手动插入会导致页面加载外部脚本,使用
append
appendTo
会导致jquery启动外部js文件的下载。但事件是使用jquery附加的,jquery启动下载,然后事件就不会触发。但是如果是页面本身启动下载,那么它就启动了。即使事件是手动添加的,在没有jquery的情况下,通过jquery添加到dom也不会触发事件

我认为应该是答案的链接


不确定jQuery为什么不起作用。使用本机API当然不是一个坏主意,但是如果您支持旧浏览器,有些浏览器不支持
document.head
属性。您需要从DOM中选择
head
元素,或者将其附加到
document.body
…此外,我认为旧IE不支持
脚本
元素的
onload
。不确定jQuery是否解决了这个问题。@斜视一下,客户端不包括IE(谢天谢地)。哇,你真幸运!:)在这种情况下,我会完全抛弃jQuery。查看注释,再次查看代码
$('').attr('src','source.js')。on('load',function(){})
被传递给
$('head')。append()
。我不确定这是在做什么?有一个从我的代码中的
$('').on('load'),…
切换到代码中的
$(this).load(…
)。在上下文中,
this
对象应该是窗口。这是否起作用,因为在所有脚本加载完成之前窗口不会启动加载?我的代码已经在
$(文档)中。准备好了吗(…
,我的问题中没有包括这个细节。
$(document).ready(function() {
    $('head')[0].appendChild(
        $('<script />').attr('src', 'source.js').on('load', function() {
            …
        })[0]
    );
});
  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('<h1>Load fired!</h1>');
  });

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