jQuery .on() 脚本插入 DOM 时未绑定

jQuery .on() not bound when script inserted into the DOM

本文关键字:DOM 绑定 插入 脚本 on jQuery      更新时间:2023-09-26

我有一个包含自定义jQuery事件处理程序的远程javascript文件。将其作为 <script src='...'></script> 元素插入到 DOM 中时,不会注册自定义事件处理程序。

但是,如果我添加与直接 JS (<script>...</script> 完全相同的脚本,则会注册事件处理程序,并且一切都按预期执行。

为什么当脚本作为远程文件插入时,事件处理程序没有绑定在 jQuery 中?

包含自定义事件处理程序的远程文件:

console.log('Before custom event handler');
$('button').on('customEvent', function(){
    console.log('customEvent Caught');
});

https://gist.github.com/2767385

将脚本插入DOM的(非工作)javascript:

var scriptNode = document.createElement('script');
    scriptNode.src = 'https://gist.github.com/raw/2767385/b9ddea612ff60b334bd2430e59903174e527a3b5/gistfile1.js';
document.body.appendChild(scriptNode);

将脚本作为内联插入DOM的(工作替代方案)javascript:

var scriptText = "console.log('Before custom event handler'); $('button').on('customEvent', function(){ console.log('customEvent Caught'); });",
    scriptNode = document.createElement('script');
scriptNode.appendChild(document.createTextNode(scriptText));
document.body.appendChild(scriptNode);

触发事件:

$('button').triggerHandler('customEvent');
正确

读取 JS,并正确执行处理程序。

JSFiddles

远程文件 - 非工作示例:http://jsfiddle.net/3CfFM/3/
使用文本 - 替代工作:http://jsfiddle.net/3CfFM/2/

发生了什么事情?

为什么当脚本作为远程文件插入时,事件处理程序没有绑定在 jQuery 中?

你错了。与远程脚本一起使用时,事件处理程序被绑定;只是需要更长的时间。浏览器在绑定处理程序之前需要发出 HTTP 请求。这意味着不会捕获您使用 triggerHandler('customEvent') 触发的原始事件,因为它的冒泡和捕获已经完成。

如果稍等片刻,然后再次单击该按钮,您将看到事件处理程序确实已绑定。您还可以通过将triggerHandler调用延迟到脚本加载来查看以下内容:

$('button').click(function() {
    var scriptNode = document.createElement('script');
    scriptNode.src = 'https://gist.github.com/raw/2767385/897cffca74411dbb542c0713bacb5a4048d6708b/gistfile1.js';
    scriptNode.onload = function() {
        $('button').triggerHandler('customEvent');
    };
    document.body.appendChild(scriptNode);
});

http://jsfiddle.net/3CfFM/4/