自制 require 函数:让浏览器轻松实现 js 文件按需加载

唉?这种文章你也点进来看,你不知道有 LABjs、RequireJS、SeaJS... 这些库吗?html

反正我是没用过这些库,什么 AMD 、CMD 哪来那么多术语... 前端的库太多了,要看各类乱七八糟的文档,看文档就想睡觉,就像学一门新语言同样,好烦啊,还不如本身写一个库呢。前端

剧透一下,实现这个功能只须要20行代码。浏览器

好了,要怎么本身写一个按需加载的库呢,为了实现按需加载:闭包

//这是咱们要实现的功能,require('str.js')时加载str.js文件,并建立一个叫str对象,等加载完毕以后执行str对象的ready方法里的函数。app

var str = require('str.js');

str.ready(show);

//要执行的函数

function show(res){

    console.log(res);

}

//str.js 文件,提供"我是str"字符串

//require.js 这个是咱们要写的库

理一理思路

一、如何加载str.js文件呢?函数

A:咱们能够插入一个<script src="str.js"></script>,这样不只加载了str.js,里面的代码还能够被浏览器自动运行呢。ui

二、如何判断str.js文件已经加载完毕?code

A:能够在str.js文件里执行一个函数,通知你们,我已经加载完了。htm

三、require('str.js')返回一个对象,这个对象要怎么和str.js相关联呢?对象

A:咱们能够建立一个叫JS['str.js']的对象,使str指向这个对象就好了。

四、我不想把代码都写进一个ready里面,我要写在不少个ready里面,加载完以后它们都能执行吗?

A:无论多少个ready,没加载完的时候,都会丢进一个队列里面先保存着,因此咱们须要一个队列。

五、加载完的那个时刻触发ready,那加载完以后我再写的ready函数,就不执行吗?

A:也会执行,因此,在加载完的那个时刻,咱们将重写ready函数。

六、这么多东西20行代码能完成吗?

A:....

执行方案

根据上诉思路,写了一个require.js文件:

function require(path){

    //好比咱们require('js/str.js') , 咱们须要获取'str.js'这个文件名
    var filename = path.split('/');
    filename = filename[filename.length-1];

    JS[filename]={
        fn:[/*这个就是(4)中提到的那个队列*/],

        //这是(2)中提到的方法,str.js文件里面执行这个方法就表明它加载完了
        ready:function(){
        
            JS[filename].fn.forEach(function(fn){
                //JS['str.js'].export就是str.js要提供的东西:'我是str'
                fn(JS[filename].export);
            });

            //这是(5)中提到的,ready函数的重写
            JS[filename].rt.ready = function(fn){
                fn(JS[filename].export);
            };
        },
        rt:{
            ready:function(fn){JS[filename].fn.push(fn)}//这个就是str对象的ready函数
        }
    };

    //这是(1)中提到的插入script标签
    var script = document.createElement('script');
    script.src = path;
    document.head.appendChild(script);

    //这是(3)中要返回的对象
    return JS[filename].rt;
}

接下来,就差str.js的写法了:

/*

    这里你想写什么代码都行,推荐写在闭包里,以避免污染全局变量

*/
JS['str.js'].export = '我是str';//这个是供你们使用的参数
JS['str.js'].ready();//执行这个函数,通知你们,str.js加载完毕了

确认一下执行结果

<!DOCTYPE html>
<script src="require.js"></script>
<script>
    var str = require('str/str.js');
    str.ready(show);

    setTimeout(function(){
        str.ready(show);
    },3000);

    //要执行的函数
    function show(res){
        console.log(res);
    }
</script>

ok,一切正常。

相关文章
相关标签/搜索