TOC
最近使用require尝试开发了一个弹窗组件,所以把一些组件化的思想和过程记录下来。
使用的库
- jQuery
- require
- jQueryUI
实现的功能
- 三种流行的弹窗
- 带有宽高位置设置
- 可以设置按钮的内容以及显示内容
- 可以设置是否模态
- 可以添加额外的皮肤
- 拥有自定义的事件机制 一个click事件触发多个自定义事件
基本思想
这个来源于网上的材料,我照着自己实现了一下,来记录一下我觉得的重点,最关键的是一种组件化的思想,也就是组件和组件之间的依赖关系。require是个非常棒的东西。 定义一个组件,然后把这个组件暴露出去 并在main里进行调用。另外一点组件最好是由一个抽象类统一进行管理,让抽象类调用一些抽象的方法,然后让具体的类进行一个实现。
调用和实现
调用方式
$('.confirm').click(function () {
new w.window().confirm({
title:"系统消息",
content:"您确定要删除这个文件吗",
confirmBtn:"是",
cancelBtn:"否",
dragHanle:".wiw_header",
hasMask:true,
maskFlash:true,
}).on("confirm",function () {
alert("sure");
}).on("cancel",function () {
alert("cancel");
})
})
以上是一个调用实例,首先添加事件然后传参进行new,其中参数用了json进行传输,我认为在不跨前后端的情况下不是很需要传入字符串形式的json,对象形式的json可以和方便的传送回调函数
因为实现了三种弹窗,所以支持alert和promot 传进去的参数类型也有所不同 在window构造函数中会设置一些默认的值,没有传参也已正常的运行
整体框架
Wiw.prototype = $.extend({},new widget.widget(),{...自定义的方法}
首先利用对象的合并,让原型对象变成一个抽象类与自定义方法的合体。
confirm:function (cfg) {
$.extend(true,this.config,cfg,{winType:"confirm"});
this.render();
return this;
}
这里是实际调用的中心, 首先会进行一个深层次的对象合并 接着执行render()方法
这个方法来源于抽象类,他扮演调用中心的角色,而具体的实现则由window来实现
render:function (container) {
this.renderUI(); //建造盒子和内容
this.handlers = {}; //初始化自定义事件容器
this.bindUI(); //绑定事件
this.syncUI(); //设置样式
$(container || document.body).append(this.boundingBox); //所有完成 添加到文档
},
所有的弹窗都被拆分成了这么几个抽象步骤,在这些方法中进行一个具体实现,可以很好的提高代码可读性。
而摧毁盒子也是如此的结构
destory:function () {
this.destructor();
this.boundingBox.off();
this.boundingBox.remove();
}
所有的方法都是公用的 比如alert 和 confirm 调用的都是同样的方法 ,但区分在于在自身的config属性中添加winType 通过对于自身类型的识别,我们可以做到不同的措施。
自定义事件的实现
on:function (type,handler) {
if(typeof this.handlers[type] == "undefined"){
console.log(type);
this.handlers[type] = [];
}//如果在字典中响应类型没有事件存储 就创建一个数组以便村粗
this.handlers[type].push(handler);
return this;
},
fire:function (type,data) {
//检测相应类型数组是否存在 存在则全部吐出来执行
//如果传进来了输入就放入参数之中调用
if(this.handlers[type] instanceof Array){
console.log("fire");
var handlers = this.handlers[type];
for(var i=0,len=handlers.length; i<len; i++){
handlers[i](data);
}
}
},
自定义事件的原理利用了堆栈结构,在执行on方法的时候 在自身handlers属性对象内部的相应type存放函数,而在fire的时候按照相应的参数type 来寻找那个数组 并且遍历都触发一遍。
样式
样式部分我利用了外联css 我认为利用css比较的方便修改 我的所有class名都使用了wiw_前缀 以保证不和其他DOM冲突
其他
- 级联 在调用的最后加上return this
- 模态 在创建弹出窗的时候在其后面加上一个覆盖整个窗口的div
- 拖动使用jQueryUI 非常方便
总结
组件化毫无疑问是我的未来学习方向,我认为学习组件最重要的是要抛弃以前那种从下往上思考的习惯,应该从抽象的层次思考,然后向下写具体的代码,只有从更高的层次看整个程序,才能写出真正可复用,可维护的代码。
地址 : https://github.com/zhangzhengyi12/require-window