使用innerHTML注入的脚本不会触发onload和onerror

时间:2016-11-17 19:11:59

标签: javascript

我正在尝试绑定onload标记的onerrorscript个事件。从src加载时工作正常。鉴于以下功能:

function injectJS(src, inline) {
    var script = document.createElement("script");

    if (inline) {
        script.innerHTML = src;
    } else {
        script.src = src;
    }

    script.onload = function() {console.log("Success!");};
    script.onerror = function() {console.log("Error!");};

    document.body.appendChild(script);
}

我很容易知道脚本是否已加载:

> injectJS("https://code.jquery.com/jquery-3.1.1.min.js");
Success!

> injectJS("https://raw.githubusercontent.com/eligrey/FileSaver.js/master/FileSaver.js");
Error!

但是当使用innerHTML注入内联JS时,脚本不会触发事件:

> injectJS("console.log(\"Yes!\");", true);
Yes!

> injectJS("console.log(\"Loaded but error...\"); error;", true);
Loaded but error...
在这些情况下,

Success!尚未登录。但是,我可以预先添加一些可以调用函数的代码,例如,一旦加载了脚本。

当出现阻止脚本首先加载的错误时会出现问题,例如语法错误:

> injectJS("console.log(\"Success! Or not..\"); syntax error;", true);

没有记录任何内容(当然,错误除外)。如何在加载前检测注入的脚本是否已加载或出错?

修改

Oriol的answer指出了我正确的方向。作为参考,这里是最终函数,它完全按照我的意愿工作并传递了5个测试用例:

function injectJS(src, inline, on_success, on_error) {
    var script = document.createElement("script");

    script.onload = on_success;
    script.onerror = on_error;

    if (inline) {
        script.innerHTML = "window.script_loaded = true; " + src;
    } else {
        script.src = src;
    }

    document.body.appendChild(script);

    if (inline) {
        var loaded = window["script_loaded"];
        window.script_loaded = false;

        if (loaded) {
            on_success();
        } else {
            on_error();
        }
    }
}

1 个答案:

答案 0 :(得分:2)

Inline scripts are loaded synchronously。所以你根本不需要这些活动。

只需使用



for(var i=images.length; i--;){
    var image = images[i];
    // do stuff with each image
}




您无法检测语法错误,但它与外部脚本一样。 function injectJS(src, inline) { var script = document.createElement("script"); script.onload = function() {console.log("Success!");}; script.onerror = function() {console.log("Error!");}; if (inline) { script.innerHTML = src; script.onload(); } else { script.src = src; } document.body.appendChild(script); } injectJS("console.log(\"Yes!\");", true);事件仅表示无法下载脚本,而不是语法错误。