使用回调异步加载JavaScript文件
我正在尝试编写一个超简单的解决方案来异步加载一堆JS文件。到目前为止,我有下面的脚本。但是,有时在脚本未实际加载时调用回调,这会导致变量未找到错误。如果我刷新页面,有时它只是工作,因为我猜文件直接来自缓存,因此比调用回调更快,这很奇怪吗使用回调异步加载JavaScript文件,javascript,ajax,asynchronous,design-patterns,Javascript,Ajax,Asynchronous,Design Patterns,我正在尝试编写一个超简单的解决方案来异步加载一堆JS文件。到目前为止,我有下面的脚本。但是,有时在脚本未实际加载时调用回调,这会导致变量未找到错误。如果我刷新页面,有时它只是工作,因为我猜文件直接来自缓存,因此比调用回调更快,这很奇怪吗 var Loader = function () { } Loader.prototype = { require: function (scripts, callback) { this.loadCount = 0;
var Loader = function () {
}
Loader.prototype = {
require: function (scripts, callback) {
this.loadCount = 0;
this.totalRequired = scripts.length;
this.callback = callback;
for (var i = 0; i < scripts.length; i++) {
this.writeScript(scripts[i]);
}
},
loaded: function (evt) {
this.loadCount++;
if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call();
},
writeScript: function (src) {
var self = this;
var s = document.createElement('script');
s.type = "text/javascript";
s.async = true;
s.src = src;
s.addEventListener('load', function (e) { self.loaded(e); }, false);
var head = document.getElementsByTagName('head')[0];
head.appendChild(s);
}
}
谢谢您的帮助。据我所知,您的代码没有任何问题,这只是Chrome中的一个bug(它也通过window.onload实现)
我会将其添加到“加载”函数中触发的函数中。如果变量存在,请执行JS代码,如果不存在,请使用setTimeout在500ms左右再次检查。为了防止您发现这一点有用,我创建了一个异步实用程序库,可以让您将上述代码编写为:
var Loader = function () {}
Loader.prototype = {
require: function (scripts, callback) {
async.map(scripts, this.writeScript, callback);
},
writeScript: function(src, callback) {
var s = document.createElement('script');
s.type = "text/javascript";
s.src = src;
s.addEventListener('load', function (e) { callback(null, e); }, false);
var head = document.getElementsByTagName('head')[0];
head.appendChild(s);
}
}
如果您正在进行大量异步调用,它有一些非常强大的功能:)
关于jQuery
$.getScript('abc.js');
上面的代码将异步加载“abc.js”脚本文件……就像Aaron说的chrome中有一个bug,但是IE和其他浏览器也有问题 我尝试了不同的方法来创建我的惰性加载程序,但我遇到了很多问题:
- 添加标记:资源管理器和其他浏览器中的脚本事件(onload、onerror等)问题
- 使用ajax阅读脚本并解析文本(使用eval,它是javascript,所以不用担心它不是邪恶的):调试非常困难(它被解析为一行,没有注释,所以您不知道哪行会出错)
- 使用ajax阅读脚本并添加带有脚本文本的标记:在所有浏览器上都非常有效; 您可以使用相同的函数创建异步和同步加载,还可以很好地控制错误、加载等(如果您了解ajax的基础知识,您应该知道如何处理各种http状态),这就是我的建议
jcors-loader.js不在Internet Explorer中工作 Index.html
<html>
<head>
<script type="text/javascript" src="/js/jcors-loader.js"></script>
<script>
JcorsLoader.load(
"js/jquery-1.8.0.js",
"/js/alertme.js",
function() {
$("#result").text("TEST OK");
}
);
</script>
</head>
<body>
<h1 id="result"></h1>
</body>
</html>
JcorsLoader.load(
“js/jquery-1.8.0.js”,
“/js/alertme.js”,
函数(){
$(“#结果”).text(“测试正常”);
}
);
alertme.js
警报(“已加载”)
这在chrome和firefox中运行良好,它显示“测试正常”和弹出窗口…但在IE(7,8,9)中没有消息或警报…任何帮助都将不胜感激 您在哪个浏览器和版本中测试此功能?在最新的WebKit中,是否也在最新的Chrome开发版本中进行了测试:(我无法使用Chrome 5.0.375.70复制此功能,从CDN加载两个脚本,从localhost加载一个脚本(包含在回调函数中执行一行所需的函数)。但是
async
标志真的有必要吗?如果你注释s.async=true;
out会发生什么?是的,不需要真正的async。谢谢:)@galambalazs这个脚本是为一个移动web应用程序编写的,幸运的是没有问题:DYou也可以测试当前的函数:例如,如果你想以这种方式加载jQuery,您可以测试全局作用域中是否存在$
函数:如果(“$”在窗口中)/*执行某些操作*代码>谢谢也添加了这个检查:)我已经在使用xui框架了,不想也包括jQuery框架,它只会增加额外的权重:)虽然我不知道jQuery可以做到这一点,谢谢getScript
没有一个回调函数,该函数在脚本执行后调用。
JcorsLoader.load(
"http://xxxx/jquery.min.js",
function() {
$("#demo").html("jQuery Loaded");
},
"http://xxxx/jquery.cookie.js",
function() {
$.cookie('not_existing');
}
);
<html>
<head>
<script type="text/javascript" src="/js/jcors-loader.js"></script>
<script>
JcorsLoader.load(
"js/jquery-1.8.0.js",
"/js/alertme.js",
function() {
$("#result").text("TEST OK");
}
);
</script>
</head>
<body>
<h1 id="result"></h1>
</body>
</html>