2010-08-19 102 views
4

今天我一直在加载动态JavaScript代码(文件)。我使用的解决方案是:动态加载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); 
    } 

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

+1

的Dupicate http://stackoverflow.com/questions/3125897/loading-scripts-dynamically/3125918#3125918 – tcooc 2010-08-19 15:05:42

+1

为什么不看看像LabJS这样的现有解决方案? http://labjs.com/ – Pointy 2010-08-19 15:06:06

+0

没有冒犯,但这是一个糟糕的设计决定的怪胎。 – Fosco 2010-08-19 15:08:22

回答

2

缺少JS库的最简单方法是使XMLHttpRequest和eval()返回。你的“onload”将会在数据返回的时候出现,而“oninit”在你评估完毕后就会立即生效。

编辑:如果你想排序这个,你可以创建一个AssetLoader,它接受一个脚本数组并且不会eval()一个脚本,直到它被取出并初始化为止。

编辑2:你也可以在评论中引用的帖子中使用script.onload的东西。 eval方法有一个小优点,因为您可以分离和控制脚本导入的加载和执行部分。

编辑3:下面是一个例子。考虑一个名为foo.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); 
} 

你会看到“脚本加载”警报“,初始化脚本“和”酒吧“。很显然,XMLHttpRequest在这里的实现并不完整,并且你可以为你希望执行脚本的任何范围做各种事情,但这是它的核心。

+0

是的,但我怎么知道脚本已经初始化? – gotch4 2010-08-19 15:12:05

+0

eval()之后脚本已经初始化。您可以在其周围放置一个try-catch块,以查看是否有任何错误阻止脚本初始化。 – sevenflow 2010-08-19 15:13:39

+0

我举了一个例子代码编辑 – sevenflow 2010-08-19 15:33:09

3

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

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

参见:jquery

+0

呃...不幸的是,这必须加载jQuery本身uhuhuhu – gotch4 2010-08-19 15:06:29

+1

+1。这样,您可以通过在回调函数中嵌套getScript调用来支持依赖性并按顺序加载它们。 – Fosco 2010-08-19 15:06:46

+0

您可以查看jQuery源代码,它可以使用普通JavaScript轻松实现,请参阅:http://gist.github。com/538106 – tszming 2010-08-19 15:20:27

-2

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

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

//script1-10.js 
increaseLoadCount(); 

比超时也许更好一点..