为什么不.on('load',...)触发脚本标记的回调?

时间:2012-05-30 19:11:28

标签: jquery onload

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

$('<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/

2 个答案:

答案 0 :(得分:2)

您应该拨打$.getScript(),这正是如此,并且正常运行。

答案 1 :(得分:2)

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

  • load事件不是气泡事件。调用的处理程序将仅挂在该特定元素上
  • appendTo()实际上没有按预期将代码提供的元素注入到DOM中

getScript()直接使用DOM函数

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

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

以下是对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)”来调用处理程序。
  3. 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为“value”,2nd为“node”。 “value”是变量“$ script”。实际注入的元素是“节点”,它不是“$ script”

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

    firefox comparison on the variable node & value

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

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