3

我有以下代码加载外部脚本并在加载时应该执行一些代码:

$('<script/>', {
    type: 'text/javascript',
    src: 'https://raw.github.com/einars/js-beautify/master/beautify.js'
}).on('load', function() {
    alert('jsb loaded' + typeof js_beautify);
}).appendTo('body');

但是,该事件永远不会触发 - 即使脚本正确加载,如已验证

window.setTimeout(function() {
    alert(typeof js_beautify);
}, 1000);

哪个警报function就好了。

演示:http: //jsfiddle.net/ThiefMaster/x2b9x/

4

2 回答 2

2

您应该调用$.getScript(),它正是这样做的,并且可以正常工作。

于 2012-05-30T19:12:58.423 回答
2

(jQuery:2.0.3) 通过appendTo()注入动态脚本标签时未触发加载事件的2个原因:

  • 加载事件不是气泡事件。调用的处理程序将仅挂钩该特定元素
  • appendTo() 并没有按预期将代码提供的元素真正注入 DOM

getScript() 直接使用 DOM 函数

document.head.appendChild( script[ 0 ] );

注入脚本标签元素。这确保标签元素实际添加到 DOM 中。而 appendTo() 将尝试使用 Ajax 从源 URL 加载脚本。然后为窗口对象而不是脚本对象触发加载事件。

以下是对 jQuery.appendTo() 的详细测试以了解原因

                var $script = $("<script>", {
                    src: this.options.url_js,
                    "data-widget": this.widgetFullName,
                    type:"text/javascript"
                }).on(
                    "load error",
                    function( evt ) {
                        script.remove();
                        if ( evt ) {
                            alert( evt.type === "error" ? 404 : 200, evt.type );
                        }
                    }
                ).appendTo("head");
  1. jQuery.on() 将使用元素作为键将事件处理程序注册到“data_priv”中
  2. 当事件发生时,jQuery 将使用“jQuery.event.dispatch.apply(eventHandle.elem, arguments)”来调用处理程序。

jQuery.appendTo() 是“追加”的别名。实际代码是

   append: function() {
    return this.domManip( arguments, function( elem ) {
        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
            var target = manipulationTarget( this, elem );
            target.appendChild( elem );
        }
    });
}

在将元素实际注入 DOM 之前,它会使用 domManip() 执行一些 ajax 操作。

  domManip: function( args, callback, allowIntersection ) {

这个函数中有2个关键变量,1是“值”,2是“节点”。“值”是变量“$script”。实际注入的元素是“节点”,而不是“$script”

  callback.call( this[ i ], node, i ); //inject the element into the DOM  

变量节点和值上的Firefox比较

这就是为什么“$script”上的“load”事件处理程序根本不会被调用的原因。

但是这个加载事件会触发两次,一次是针对加载的元素,(这里是节点),一次是针对window对象的。如果您的处理程序与窗口对象挂钩,它将被调用。

于 2013-11-20T03:39:32.283 回答