动态加载Javascript文件并加载完成事件

动态加载Javascript文件并加载完成事件,javascript,dynamic,loading,Javascript,Dynamic,Loading,今天我一直在加载动态javascript代码(文件)。我使用的解决方案是: function loadScript(scriptUrl) { var head = document.getElementsByTagName("head")[0]; var script = document.createElement('script'); script.id = 'uploadScript'; script.type = 'text

今天我一直在加载动态javascript代码(文件)。我使用的解决方案是:

function loadScript(scriptUrl) {
        var head = document.getElementsByTagName("head")[0];
        var script = document.createElement('script');
        script.id = 'uploadScript';
        script.type = 'text/javascript';
        script.src = scriptUrl;
        head.appendChild(script);
    }

问题是我不知道如何确定脚本内容何时执行。由于脚本包含类(well JS类),我写下了一个通过setTimeout调用的函数,并检查这些对象是否已定义。这是不灵活的,因为它不是自动的。所以有没有办法加载这些脚本并在执行时发出可靠的通知?

您可以使用jquery的getScript并传递回调函数

$.getScript("test.js", function(){
   alert("Script loaded and executed.");
 });

请参阅:。

除了JS库之外,最简单的方法是生成XMLHttpRequest并使用eval()返回。您的“onload”是在返回数据时,而“oninit”则是在您评估之后

编辑:如果要对此进行排序,可以创建一个AssetLoader,它接受一个脚本数组,并且在获取并初始化之前不会对脚本求值()

编辑2:您还可以在评论中引用的帖子中使用script.onload内容。eval方法有一点优势,即您可以分离和控制脚本导入的加载和执行部分

编辑3:下面是一个例子。考虑一个名为Fo.js的文件,包含以下内容:


function foo () {
    alert('bar');
}
然后从浏览器中的其他页面执行以下操作:



function initScript (scriptString) {
    window.eval(scriptString);
}

function getScript (url, loadCallback, initCallback, callbackScope) {

    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onreadystatechange = function (e) {

        if (req.readyState == 4) {
            if (loadCallback) loadCallback.apply(callbackScope);
            initScript.call(null, req.responseText);
            if (initCallback) initCallback.apply(callbackScope);
        }

    }

    req.send();

}

function fooScriptLoaded () {
    alert('script loaded');
}

function fooScriptInitialized () {
    alert('script initialized');
    foo();
}

window.onload = function () {
    getScript('foo.js', fooScriptLoaded, fooScriptInitialized, null);
}


您将看到警报“脚本已加载”、“脚本已初始化”和“bar”。显然,这里的XMLHttpRequest的实现并不完整,您可以在任何范围内执行脚本,但这是它的核心。

您可以使用一个计数器变量和一种回调:

var scriptsToLoad = 10;
var loadedScripts = 0;
//...
function increaseLoadCount() {
loadedScripts++;
if(loadedScripts == scriptsToLoad) {
alert("start here");
}
}

//script1-10.js
increaseLoadCount();

也许比超时好一点。

为什么不看看像LabJS这样的现有解决方案呢?无意冒犯,但这意味着一个糟糕的设计决策。LabJs在jQuery中失败了,我今天早上试过了……可能是重复的。。。不幸的是,这必须加载jQuery本身uhu+1。通过这种方式,您可以通过在回调函数中嵌套getScript调用来支持依赖关系并按顺序加载它们。您可以查看jQuery源代码,它可以使用普通JavaScript轻松实现,请参见:注意,根据当前:加载脚本后会触发回调,但不一定执行。i、 它不保证脚本的执行。eval()后,脚本已初始化。您可以在脚本周围抛出try-catch块,查看是否有任何错误阻止脚本初始化。