日期:2014-05-16  浏览次数:20350 次

最近在看SEAJS,于是遍自己也写了个关于模块化JS的框架

http://websiteui.com/html5/js/www/page/demo.html

?

上面是演示地址

?

?

使用方法:

?

(首先声明这框架的每个HTML里都有对应的PAGE文件。如DEMO.HTML,必然在JS里有对应的DEMO.JS)

?

首先做页面的工作:

在demo.html里调用require.js,执行初始化init('对应的js文件')

?

<script src="../js/require.js"></script>
<script>
	init('demo');
</script>
?

?

这样require就会去请求对应page目录下的JS文件----demo.js

?

然后是PAGE目录下的JS文件:

先在demo.JS中,指定需要用到哪些控件,如autocomplete 、 dialog,

?

?

require('autocompele.js')
require('dialog.js')
?

?

接着在demo.js中定义

?

?

defined('demo',function(){
   ooxx()~~~~
})
?

?

便完成了整个页面JS的加载定义及使用,至于autocomplete dialog里需要用到哪些包,这是控件所关心的,而不需要user在这里定义。

?

?

至于所调用的JS文件 也一样

如autocomplete.js

?

?

require('../js/core/core.js');
require('../js/core/extend.js');
defined('widget.autocomplete',function(){
    我要开始做autocomplete了
})

?只需要定义控件所需要的模块即可

?

?

?

?

?


实现原理:

?

这里只说原理不分析代码

?

步骤1、 加载:

?

首先有2个函数,一个叫require,一个叫defined

?

require决定每个模块需要加载什么 defined决定具体模块做些啥事

?

?

另外有个空对象list

这个是所加载脚本的列表对象,每创建一个SCRIPT的请求,遍添加一项记录,同时设置该条状态为0,完成加载后,设置状态为1;

?

require函数如何工作:

如:require('a.js');

?

1 根据参数a.js,在HEAD创建SCRIPT标签,并且记录在list对象中,加载完成后,修改标记状态1,并且遍历list的所有记录是否全部为1,如果全部为1时,说明加载完成 可以开始执行。

举例说明:

如:我有A B 3个JS需要加载,A依赖B

?

那我在require.js加载完成后,首先会去请求A.JS,此时,list对象变成为了 {'a.js':0},

?

a.js在加载完成后,自然会运行a.js里的代码,当发现a.js里又有require函数请求了b.js,那便会再次更改list对象为{a.js:0,b.js:0},

?

这时候a.js运行结束,执行a.js的onload,修改list对象为{a.js:1,b.js:0},然后对list进行检查,如果有一项为0 说明加载还未完成,

?

等b.js加载完成后,再次运行onload 把list对象改为{a.js:1,b.js:1},再次进行检查,发现全部为1,则加载步骤已经完成。

?

这样加载步骤就OK了,执行onload事件,开始运行具体库里的函数。

?

步骤二,整理函数包

?

这里我采用的YUI的做法

有2个对象 分别是requireOrder 和 model,

?

requireOrder 里 定义了所有函数名的执行顺序,

model 则接受了每个JS包加载完成的defined函数,

?

?

由于加载JS文件的顺序是不定的,往往功能包优先于核心包加载完成。甚至有可能由于网速和JS文件大小的原因,加载完成后的顺序会很混乱

如加载顺序为

控件->功能->核心代码

?

或者因为网络问题,添加到model里的函数顺序变成了

功能->控件->核心代码

?

那按这样的顺序必然会出错

?

所以就在requireOrder里定义好顺序为

核心代码->功能->控件

?

强制按requireOrder里的顺序去执行即可。

?