• 为自定义对象添加自定义事件


    由于javascript并没有自己的事件系统,借助于DOM的事件系统,如果只涉及到javascript对象就歇菜了。下面是一个仿制品,不要指望有事件冒泡这东西。

          if(typeof Array.prototype.forEach !== "function"){
            Array.prototype.forEach =  function (fn, scope) {
              for(var i=0,n=this.length>>>0;i<n;i++){
                i in this && fn.call(scope,this[i],i,this)
              }
            }
          }
          var EventDispatcher = {
            $A:function(iterable){
              return Array.prototype.slice.call(iterable)
            },
            createEvents:function(){
              this._listeners = {};
              var names =  this.events || [],name,type;
              names.forEach(function(type){
                name ="on"+ type.replace(/_([a-z])/g, function($1,$2){
                  return $2.toUpperCase()
                }).replace(/^\w/, function (s) {
                  return s.toUpperCase();
                });
    
                if(typeof this[name] ==="undefined"){
                  this[name] = function(){
                    var args = this.$A(arguments);
                    return this.attachEvent.apply(this,[type].concat(args))
                  }
                }
              },this)
            },
            hasEvent:function(type){
              return (this._listeners[type] instanceof Array && this._listeners[type].length > 0);
            },
            attachEvent:function(){
              var args = this.$A(arguments),
              type = args.shift(), callback = args.shift();
              if (!this.hasEvent(type)) 
                this._listeners[type] = []; 
              var listeners = this._listeners[type]; 
              listeners.push({ callback:callback,args: args });
            },
            detachEvent:function(type,callback){
              if (this.hasEvent(type)) {
                var listeners = this._listeners[type],listener;
                if(typeof callback === "undefined"){
                  delete this._listeners[type];
                }else{
                  for(var i=0,n=listeners.length;i<n;i++){
                    if (listeners[i].callback === callback){
                      listeners.splice(i, 1);
                      return;
                    }
                  }
                }
              }
            },
            fireEvent:function(){
              var args = this.$A(arguments),type = args.shift();
              if (!this.hasEvent(type)) return ;
              var listeners = this._listeners[type];
              listeners.forEach(function(listener){
                listener.callback.apply(this, listener.args.concat(args))
              },this);
            }
          }
    

    严格来说,这不能算一个类,应该叫接口的东西。当目标类实现它(把EventDispatcher的成员变成目标类的成员),并在原型中提供一个events的字符串数组成员后,我们调用了createEvents,它就拥有事件般的行为,由于没有了DOM的监控,我们需要fireEvent来触发事件。

    一个例子:

          var Person = function(name){
            this.name = name
          }
          Person.prototype = {
            events:["layout"]
          }
          var include = function(Concrete,Interface){//使用ruby式的命名方式,用于添加实例成员
            for(var prop in  Interface) {
              Concrete.prototype[prop] = Interface[prop];
            }
          }
          include(Person,EventDispatcher );
          var p = new Person("司徒正美")
          p.createEvents()
          p.onLayout(function(name){
            alert(name)
          });
          p.onLayout(function(name){
            alert(name+"!!")
          });
          p.fireEvent("layout","参数")//依次弹出 "参数" "参数!!"
    

  • 相关阅读:
    读书计划
    《梦断代码》读书笔记1
    合作项目5
    合作项目4
    合作项目3
    电梯调度需求分析
    合作项目2
    四则运算3程序
    合作编程
    四则运算某模块程序测试
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1703446.html
Copyright © 2020-2023  润新知