模拟事件的底层实现

https://www.zhangxinxu.com/wordpress/2012/04/js-dom%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6/#comment-326125

实例详解

<script>
    /*
        var mode = {
            a:[],
            b:[],
            c:[]
        }
    */
    var EventTarget = function(){
        this._listener = {};
    }

    EventTarget.prototype = {
        constructor : EventTarget,
        //单个加入运动时间
        addEvent : function(type,fn){
            //判断type和fn是否符合条件
            if (typeof this._listener[type] === 'undefined' && typeof fn === 'function')
            {
                //如果不是数组,添加数组
                this._listener[type] = [fn];
            }else {
                //如果是数组则推入fn
                this._listener[type].push(fn);
            }
            return this;
        },
        addEvents : function(obj){
            //判断obj的条件
            obj = (typeof obj === 'object') ? obj : {};
            var type;
            //传入的参数
            for (type in obj)
            {    
                //判断type的类型
                if (type && typeof obj[type] === 'function')
                {
                    this.addEvent(type,obj[type]);
                }
            }
            return this;
        },
        fireEvent : function(type){
            if (type && this._listener[type])
            {
                var Events = {
                    type:type,
                    target:this
                };
                /*
                    不能用这种模式,如果函数内部有this,则报错
                    this._listener[type][start]();
                */
                //传入this,在函数内部有要求用this的时候
                for (var i=0,len=this._listener[type].length;i<len;i++)
                {
                    this._listener[type][i].call(this,Events);
                }
            }
            return this;
        },
        fireEvents : function(array){
            if (array instanceof Array)
            {
                for (var i=0,len=array.length;i<len ;i++ )
                {
                    this.fireEvent(array[i]);
                }
            }
            return this;
        },
        removeEvent : function(type,fn){
            var listeners = this._listener[type];
            if (listeners instanceof Array)
            {
                if (typeof fn === 'function')
                {
                    for (var i=0,len=listeners.length;i<len ;i++ )
                    {
                        if (listeners[i] === fn)
                        {
                            this._listener[type].splice(i,1);
                        }
                    }
                //如果填写的第二个是数组
                }else if (fn instanceof Array)
                {
                    for (var j=0,len2=fn.length;j<len2 ; j++)
                    {
                        //传入参数进行计算
                        this.removeEvent(type,fn[j]);
                    }
                }else {
                    delete this._listener[type];
                }
            }
            return this
        },
        removeEvents : function(params){
            //如果params是数组
            if (params instanceof Array)
            {
                for (var i=0,len=params.length;i<len ;i++ )
                {
                    this.removeEvent(params[i]);
                }
            }else if (Object.prototype.toString.call(params) === '[object Object]')
            {
                var type;
                for (type in params)
                {
                    this.removeEvent(type,params[type]);
                }
            }
            return this;
        }
    }

    var myEvents = new EventTarget();
    myEvents.addEvents({
        "once": function() {
            alert("该弹框弹出一次!"); 
            //this.removeEvent("once");
        },
        "infinity": function() {
            alert("每次点击页面,该弹框都会出现!");    
        }
    });
    console.log( myEvents );
  </script>
原文地址:https://www.cnblogs.com/jokes/p/9791616.html