首页 > 代码库 > 模块加载简单实现

模块加载简单实现

代码仍有问题,就是导入jQuery后无法使用$问题。想参考RequireJS的做法(先去研究下): 
require([‘jquery‘, ‘underscore‘, ‘backbone‘], function ($, _, Backbone){
    // some code here
});
本代码为原创,但有一些部分参考阮一峰老师的博客和RequireJS源码。 
注意Test.html中在测试ModuleLoader之前先通过
<script type="text/javascript" src="http://www.mamicode.com/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="http://www.mamicode.com/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>
?