SeaJs模块化开发

来源:互联网 发布:台账软件 编辑:程序博客网 时间:2024/05/24 22:43

如今的网页越来越像桌面程序,网页上加载的javascript也越来越复杂,coder们不得不开始用软件工程的思维去管理自己的代码。Javascript模块化编程,已经成为一个非常迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。但是,Javascript不是一种模块化编程语言,它不支持"类"(class),更遑论"模块"(module)了。(正在制定中的ECMAScript标准第六版将正式支持"类"和"模块",但还需要很长时间才能投入实用。)


说了半天概念应该印象还不深刻,我们就来看一个例子用来演示sea.js的基本用法。首先define传入的参数是对象和字符串的情况,我先举一个参数的对象的例子,传字符串大同小异。来看代码:

 
1,我先来定义一个模块m1.js:
define({a:"这里是属性a的值"});
define传入的是一个对象字面量。现在这个东东就可以叫做一个模块了~我想在页面一加载的时候就把a的值alert出来,怎么做呢?继续往下看。
 
2,在页面上引入这个模块:
 
1 seajs.use('./m1.js',function(ex){
2      alert(ex.a);
3  }); //弹出“这里是属性a的值”
翻译得直白一点,大意就是:
 
seajs : Hi~m1.js,我现在要用(use)你了,然后把你的公开接口(exports)存到我回调函数的参数(ex)里,你把想给我调用的东东放到这个参数里吧~么么哒
 
m1.js : 好的,我定义的对象字面量放到接口里给你了,拿去尽管刷~
 
然后……a的值就弹出来了。很愉快的一次交易。PS:页面所调用的模块就为整个web应用的js入口。本例中js的入口就是m1.js。接下来再来看看如果define的参数是个函数的情况。
 
1,先定义一个模块m2.js:
复制代码
1 define(function(require,exports,module){
2     var var1 = "这是要alert出来的值";//私有变量,没有通过接口返出去的其他模块不能访问
3     function alerts(){
4         alert(var1);
5     }
6     exports.alerts = alerts;//将需要公开的方法存入exports接口中
7 });
复制代码
2,在页面上引入这个模块并执行模块m2.js公开的方法:
 
1 seajs.use('./m2.js',function(ex){
2      ex.alerts();//ex中存的有m2.js中的公开对象
3 }); //弹出“这是要alert出来的值”
到这里可以简单地说一下factory方法的三个形参的意义了(个人理解):
 
require : 提供了引入机制,提供了一种方式来建立依赖,和C中的include和java中的import类似;
 
exports : 提供了导出机制,提供了私有和共有分离,未使用exports语句导出的变量或者函数,其他模块即使引用此模块也不能使用;
 
module : 提供了模块信息描述。
 
是不是思路贱贱清晰了呢?刚才我们的例子中只是从页面调用模块的用法,模块之间互相调用还没有体现,SO,接下来就以m1.js和m2.js两个模块作为例子来尝试一下 模块之间互相调用。
 
1,首先m1.js模块不变:
 
1 define({a:"这里是属性a的值"});
2,m2.js模块要依赖(require)m1.js:
 
复制代码
1 define(function(require,exports,module){
2     var var1 = "这是要alert出来的值";//私有变量,没有通过接口返出去的其他模块不能访问
3     var var2 = require('./m1.js').a;//这里就是m2.js模块调用m1.js的方式:var2的值等于当前模块所依赖的m1.js对外接口中属性a的值
4     function alerts(){
5         alert(var2);
6     }
7     exports.alerts = alerts;//将需要公开的方法存入exports接口中
8 });
复制代码
3,页面上引入m2.js模块(同上一个例子),结果就会把a的属性值给alert出来~
 
 
 
五、实例:模块化的拖拽个窗口缩放
 
 
 
当然,上面几个例子是简单到不能再简单的例子,估计亲们也已经看出来一些道道,但个人感觉还是没能体现出模块化开发的优势。那下面就来看一个实例:模块化的拖拽个窗口缩放。先看一下效果图:
 
 
 
PS:效果图中的红色区域要先定缩放的范围,即宽高0px-宽高500px。要写这样一个需求的例子,按照之前的编程习惯你会怎么写?反正在之前,我是会把所有的功能写到一个js文件里,效果出来就行,随你们怎么胡搅蛮缠。而自从认识了模块化开发,内心不止一次告诉自己,拿到需求bigger一定要高,一定要高(虽然require.js和sea.js这两个东东在圈内多多少少还是有些争议)……
 
废话少说,首先来分析一下需要划分多少个模块吧:
 
1,一开始就要有个入口模块的吧?恩,必须的!入口模块Get√~
 
2,既然是拖拽,要有个拖拽模块吧?恩,必须的!拖拽模块Get√~
 
3,既然要缩放,要有个缩放模块吧?恩,必须的!缩放模块Get√~
 
4,既然限定缩放范围<=500px,那还要有个限定缩放范围的模块吧?恩,这个可以有,但为了以后调整范围数值方便,还是单列个模块吧。限定缩放范围模块Get√~
 
到这里我们就把本需求划分成了四个模块:
 
·  入口模块:main.js
 
·  拖拽模块:drag.js
 
·  缩放模块:scale.js
 
·  限定缩放范围模块:range.js
 
首先,是页面引入入口模块(我尽量把注释都写在代码中,以便对照代码,这样也就不用写大片大片的文字了~):
1  <script>
2     seajs.use('./js/main.js');//没有callback函数表明引入后直接执行入口模块
3 </script>
接下来看看入口模块(main.js)里都应该有些神马东东吧:
 
复制代码
 1 //入口模块
 2 define(function(require,exports,module){
 3     var $id = function(_id){return document.getElementById(_id);}
 4     var oInput = $id("button1");
 5     var div1 = $id("div1");
 6     var div2 = $id("div2");
 7     var div3 = $id("div3");//以上是获取页面元素的几只变量
 8     require('./drag.js').drag(div3);//引入拖拽模块,执行拖拽模块接口中的drag方法并传参
 9     exports.oInput = oInput;
10     oInput.onclick = function(){
11         div1.style.display = "block";
12         require('./scale.js').scale(div1,div2);//引入缩放模块,执行缩放模块接口中的scale方法并传参
13     }
14 });
复制代码
恩,还真是全面呢,把拖拽模块和缩放模块都引进来了。看看拖拽模块(drag.js)吧~
 
复制代码
 1 //拖拽模块
 2 define(function(require,exports,module){
 3     //这个方法就是实现拖拽的方法,不用详述了吧?
 4     function drag(obj){
 5         var disX = 0;
 6         var disY = 0;
 7         obj.onmousedown = function(e){
 8             var e = e || window.event;
 9             disX = e.clientX - obj.offsetLeft;
10             disY = e.clientY - obj.offsetTop;
11             document.onmousemove = function(e){
12                 var e = e || window.event;
13                 var l = require('./range.js').range(e.clientX - disX, document.documentElement.clientWidth - obj.offsetWidth,0);
14                 var t = require('./range.js').range(e.clientY - disY, document.documentElement.clientHeight - obj.offsetHeight,0);
15                 obj.style.left = l + "px";
16                 obj.style.top = t + "px";
17             }
18             document.onmouseup = function(){
19                 document.onmousemove = null;
20                 document.onmouseup = null;
21             }
22         }
23     }
24     exports.drag = drag;//返回拖拽模块中想要被公开的对象,也就是在本模块中定义的drag方法。注意有参数~
25 });
复制代码
接下来是缩放模块(scale.js)。缩放模块还需要调用 限定缩放范围模块 (range.js) 的哦~这点不要搞忘了。
 
复制代码
 1 //缩放模块
 2 define(function(require,exports,module){
 3     //这个方法就是obj2控制obj1改变大小的方法,也不再详述啦~
 4     function scale(obj1,obj2){
 5         var disX = 0;
 6         var disY = 0;
 7         var disW = 0;
 8         var disH = 0;
 9         obj2.onmousedown = function(e){
10             var e = e || window.event;
11             disX = e.clientX;
12             disY = e.clientY;
13             disW = obj1.offsetWidth;
14             disH = obj1.offsetHeight;
15             document.onmousemove = function(e){
16                 var e = e || window.event;
17                 var w = require('./range.js').range(e.clientX - disX + disW,500,100);//看这里看这里,引入了限定范围的range.js模块~
18                 var h = require('./range.js').range(e.clientY - disY + disH,500,100);
19                 obj1.style.width = w + "px";
20                 obj1.style.height = h + "px";
21             }
22             document.onmouseup = function(){
23                 document.onmousemove = null;
24                 document.onmouseup = null;
25             }
26         }
27     }
28     exports.scale = scale;//将需要公开的对象存入模块接口中,以便其他模块调用~
29 });
复制代码
最后就是限定范围的模块(range.js)了。
 
复制代码
 1 //限定拖拽的范围模块
 2 define(function(require,exports,module){
 3     function range(inum,imax,imin){
 4         if(inum > imax){
 5             return imax;
 6         }else if(inum < imin){
 7             return imin;
 8         }else{
 9             return inum;
10         }
11     }
12     exports.range = range;
13 });

0 0
原创粉丝点击