说在开头 

前面博客写了一个模拟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();
    }
  }


闲扯

周末,公司真安静;一个人在公司写写博客,听听歌,真好。