代码仍有问题,就是导入jQuery后无法使用$问题。想参考RequireJS的做法(先去研究下):
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
// some code here
});
本代码为原创,但有一些部分参考阮一峰老师的博客和RequireJS源码。
注意Test.html中在测试ModuleLoader之前先通过
<script type="text/javascript" src="./ModuleLoader.js"></script>
引入ModuleLoader.js
到目前为止我发现一个局限性(解决了这些局限性模块加载器的通用性就更好了,当然还有很多其他局限性):
A、因为ModuleLoader中的_load函数是通过动态追加<script>...</script>到<body>标签上的方法,所以该模块加载器只有等<body>加载完了才能使用
B、...
1. [代码]ModuleLoader.js
/**
* js模块加载器简单实现,代码原创,转载请保留原作者名称
* @author jxqlovejava
*/
(function(window, document, undefined) {
var ModuleLoader = function() {
};
var _loadedFiles = {};
// 动态异步加载JS文件
var _load = function(jsFilePath, callback) {
if(!jsFilePath)
return;
var js = document.createElement('script');
js.setAttribute('src', jsFilePath);
js.setAttribute('type', 'text/javascript');
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
if(callback && typeof callback === "function") {
callback();
}
js.onload = js.onreadystatechange = null;
}
};
document.body.appendChild(js);
}
/**
* file为模块文件路径(必须以.js为后缀)
* dependencyFiles是file模块依赖的模块的路径数组
* callback是加载完毕后要执行的回调函数
* @param String file国旗图标
* @param String[]
* @param callback
*/
ModuleLoader.prototype.require = function(file, dependencyFiles, callback) {
if(_loadedFiles[file]) { // 如果已经加载过,则直接返回
console.log(file + "之前已被加载!");
if(callback && typeof callback === "function") {
callback();
}
return;
}
dependencyFiles = dependencyFiles || [];
for(var i = 0; i < dependencyFiles.length; i++) {
var curFile = dependencyFiles[i];
if(_loadedFiles[curFile]) {
console.log(curFile + "之前已被加载!");
continue;
}
else {
_load(curFile);
_loadedFiles[curFile] = true;
}
}
// 加载完了所有依赖模块后,再加载file模块并在加载完成后执行callback函数
_loadedFiles[file] = true;
_load(file, callback);
}
window.ModuleLoader = ModuleLoader;
}) (window, document);
2. [文件] jquery.js ~ 262KB 下载(9)
3. [代码]ModuleA.js
function test() {
console.log("ModuleA: test()函数执行!");
}
function add(a, b) {
return a+b;
}
4. [代码]ModuleB.js
// getjQueryVersion()函数必须等jQuery.js模块加载完毕才能调用
function getjQueryVersion() {http://www.huiyi8.com/guoqi/
console.log("ModuleB: getjQueryVersion> " + $.fn.jquery);
}
// testAdd函数必须等ModuleA.js模块加载完毕才能调用
function testAdd(a, b, expected) {
console.log("ModuleB: testAdd> (" + a + " + " + b + ") => " + expected + ((a+b)==expected));
}
5. [代码]Test.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>Index Page</title>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript" src="./ModuleLoader.js"></script>
<script type="text/javascript">
var moduleLoader = new ModuleLoader(); // 实例化模块加载器对象
// 测试加载独立模块ModuleA.js
moduleLoader.require("ModuleA.js", [], function() { test(); }); // 加载ModuleA.js模块并测试其中的test()函数
moduleLoader.require("ModuleA.js"); // 重复加载ModuleA.js模块
// 测试加载依赖jQuery.js模块和ModuleA.js模块的ModuleB.js模块
moduleLoader.require("ModuleB.js", ["jquery.js", "ModuleA.js"], function() {
testAdd(1, 2, 3);
getjQueryVersion();
});
</script>
</body>
</html>
/**
* js模块加载器简单实现,代码原创,转载请保留原作者名称
* @author jxqlovejava
*/
(function(window, document, undefined) {
var ModuleLoader = function() {
};
var _loadedFiles = {};
// 动态异步加载JS文件
var _load = function(jsFilePath, callback) {
if(!jsFilePath)
return;
var js = document.createElement('script');
js.setAttribute('src', jsFilePath);
js.setAttribute('type', 'text/javascript');
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
if(callback && typeof callback === "function") {
callback();
}
js.onload = js.onreadystatechange = null;
}
};
document.body.appendChild(js);
}
/**
* file为模块文件路径(必须以.js为后缀)
* dependencyFiles是file模块依赖的模块的路径数组
* callback是加载完毕后要执行的回调函数
* @param String file国旗图标
* @param String[]
* @param callback
*/
ModuleLoader.prototype.require = function(file, dependencyFiles, callback) {
if(_loadedFiles[file]) { // 如果已经加载过,则直接返回
console.log(file + "之前已被加载!");
if(callback && typeof callback === "function") {
callback();
}
return;
}
dependencyFiles = dependencyFiles || [];
for(var i = 0; i < dependencyFiles.length; i++) {
var curFile = dependencyFiles[i];
if(_loadedFiles[curFile]) {
console.log(curFile + "之前已被加载!");
continue;
}
else {
_load(curFile);
_loadedFiles[curFile] = true;
}
}
// 加载完了所有依赖模块后,再加载file模块并在加载完成后执行callback函数
_loadedFiles[file] = true;
_load(file, callback);
}
window.ModuleLoader = ModuleLoader;
}) (window, document);
2. [文件] jquery.js ~ 262KB 下载(9)
3. [代码]ModuleA.js
function test() {
console.log("ModuleA: test()函数执行!");
}
function add(a, b) {
return a+b;
}
4. [代码]ModuleB.js
// getjQueryVersion()函数必须等jQuery.js模块加载完毕才能调用
function getjQueryVersion() {http://www.huiyi8.com/guoqi/
console.log("ModuleB: getjQueryVersion> " + $.fn.jquery);
}
// testAdd函数必须等ModuleA.js模块加载完毕才能调用
function testAdd(a, b, expected) {
console.log("ModuleB: testAdd> (" + a + " + " + b + ") => " + expected + ((a+b)==expected));
}
5. [代码]Test.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>Index Page</title>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript" src="./ModuleLoader.js"></script>
<script type="text/javascript">
var moduleLoader = new ModuleLoader(); // 实例化模块加载器对象
// 测试加载独立模块ModuleA.js
moduleLoader.require("ModuleA.js", [], function() { test(); }); // 加载ModuleA.js模块并测试其中的test()函数
moduleLoader.require("ModuleA.js"); // 重复加载ModuleA.js模块
// 测试加载依赖jQuery.js模块和ModuleA.js模块的ModuleB.js模块
moduleLoader.require("ModuleB.js", ["jquery.js", "ModuleA.js"], function() {
testAdd(1, 2, 3);
getjQueryVersion();
});
</script>
</body>
</html>