说在开头
前面博客写了一个模拟select的组件,文中还说到了一个问题;那天晚上想了一个方案第二天试了一下,是可以的;前几天一直赶进度,乘着周末分享出来。
重点,重点
自己仔细分享了出问题的原因有2个
1.缺少一个组件(组件被初始化1次,就需要标示一下)的唯一标示;
2.没有在子类中重写handlers,即实例化;导致on,fire时,this指针指向出错;
下面分别就上面提出解决方案。
缺少唯一标示:
这个问题让我自己想到以前解决ajax缓存时的方案,即在请求的url中加一个时间戳。
所以,通过时间戳给每一次组件加一个时间戳作为自己的唯一id;
重点代码如下:
function Uselect() { if(this instanceof Uselect) { this.config = { container:null,//组件的父容器 skin:null,//皮肤 readOnly: true,//输入框是否只读 maxCount:5,//最大展示数量,超过时,出现滚动条 selectHandler:null,//选中回调 dataType:0,//数据类型0,1 data:"",//数据,如果自定义拼装,请使用li标签 top:15,//下拉距顶位置,主要用于微调 width:120,//input,以及下拉的宽度 liHeight:30//下拉li的高度 }; this.isShow = false;//局部变量,仅限组件内部使用 this.id = new Date().getTime(); } else { return new Uselect(); }
组件被new一次,就有一个唯一的id,而且不会重复;
然后就是widget类绑定和执行自定义事件时,通过id进行区分
重点代码如下:
//绑定自定义事件 on:function(type,handler) { if ("undefined" === typeof this.handlers[type + this.id]) { this.handlers[type + this.id] = []; } this.handlers[type + this.id].push(handler); return this; }, //依次触发自定义事件 fire:function(type, data) { if ("[object Array]" === Object.prototype.toString.call(this.handlers[type + this.id])){ var handlers = this.handlers[type + this.id]; var len = handlers.length; for (var i = 0; i < len; i++) { handlers[i](data); } return this; } }
给每一个绑定事件的type这样处理一下:type + this.id
这样相同事件在on绑定时的事件type实际上时,type + this.id,永远不会重复;
同理,执行自定义事件也是按照type + this.id的事件类型执行!
当然,这里的type + this.id只是简单的拼唯一字符串的方式,你也可以通过type+"-"+ this.id,或者type+"_"+ this.id等等。
重写handlers
这个比较好理解,当我们在uselect构造函数中重写this.handlers后,name当注册和执行事件时,this就指向当前的对象,handlers就实例化。代码比较简单,在构造函数重写handlers就可以了;
代码如下:
function Uselect() { if(this instanceof Uselect) { this.config = { container:null,//组件的父容器 skin:null,//皮肤 readOnly: true,//输入框是否只读 maxCount:5,//最大展示数量,超过时,出现滚动条 selectHandler:null,//选中回调 dataType:0,//数据类型0,1 data:"",//数据,如果自定义拼装,请使用li标签 top:15,//下拉距顶位置,主要用于微调 width:120,//input,以及下拉的宽度 liHeight:30//下拉li的高度 }; this.isShow = false;//局部变量,仅限组件内部使用 // this.id = new Date().getTime(); this.handlers = {}; } else { return new Uselect(); } }
闲扯
周末,公司真安静;一个人在公司写写博客,听听歌,真好。