1. 程式人生 > >寫一個addEventListener以及removeEventListener

寫一個addEventListener以及removeEventListener

set rem 第一步 接受 lis 數控 成長 註意 rop

第一步:對象屬性賦值為函數,對象內部函數控制年齡這一參數變化,同時成長事件也執行。

  class Person{
        constructor(){
            this.name = ‘‘;
            this.age = 0;
            this.growup()//不斷成長
            this.growEvent = null//成長經歷的事情
        }
        setName(val){
            this.name = val
        }
        growup(){
            let _this 
= this; setInterval(()=>{ _this.age++; if(_this.growEvent instanceof Function){//判斷是不是函數 _this.growEvent() } },100) } } let hx = new Person() hx.setName(‘韓信‘) hx.growEvent = function
(){ if(this.age == 18){ console.log(‘開始參軍啦‘) } }

繼續思考:成長事件只能接受一個函數,那麽如果是多個函數呢?韓信要打仗,要建功立業的呀。可以很快的想到growEvent換成數組來接受多個函數。

那麽,growEvent就要靠Push進數組了,而不是粗暴的賦值了。成長事件執行的時候也不再是上門的_this.growEvent,而是循環了。

  class Person{
    	constructor(){
    		this.name = ‘‘;
    		this.age = 0;
    		this.growup()//不斷成長
    		this.growEvent = []//需要接受多個函數
    	}
    	setName(val){
    		this.name = val
    	}
    	growup(){
    		let _this = this;
    		setInterval(()=>{
    			_this.age++;
    			_this.growEvent.forEach(cb=>{
    				if(cb instanceof Function){
    					cb.call(this)//需要註意更改this指向,不然指向window
    				}
    			})
    		},100)
    	}
    	
    }
    let hx = new Person()
    hx.setName(‘韓信‘)
    hx.growEvent.push(function(){
    	if(this.age == 18){
    		console.log(‘開始參軍啦‘)
    	}
    })
    hx.growEvent.push(function(){
    	if(this.age == 20){
    		console.log(‘當上小隊長啦‘)
    	}
    })

上面的這種方式成長事件采用直接Push的方式看著好像有點辣眼睛,那麽我們可以添加一個addEventListener方法來幫我們Push

class Person{
        constructor(){
            this.name = ‘‘;
            this.age = 0;
            this.growup()//不斷成長
            this.growEvent = []//需要接受多個函數
        }
        setName(val){
            this.name = val
        }
        growup(){
            let _this = this;
            setInterval(()=>{
                _this.age++;
                _this.growEvent.forEach(cb=>{
                    if(cb instanceof Function){
                        cb.call(this)//需要註意更改this指向,不然指向window
                    }
                })
            },100)
        }
        addEventListener(cb){
            if(cb instanceof Function){
                this.growEvent.push(cb)
            }
        }
        
    }
    let hx = new Person()
    hx.setName(‘韓信‘)
    hx.addEventListener(function(){
        if(this.age == 18){
            console.log(‘開始參軍啦‘)
        }
    })
    hx.addEventListener(function(){
        if(this.age == 20){
            console.log(‘當上小隊長啦‘)
        }
    })

寫到了這裏看上去好像有點那啥的樣子了。那麽,假設成長事件需要一個名字呢?比如,hx,addEventListener("marry",funciton(){})

那我們就需要繼續對growEvent繼續改裝,改成對象形式,每個屬性的屬性值都是一個數組。

在Push事件,以及執行事件的時候也要更改一下。

class Person{
        constructor(){
            this.name = ‘‘;
            this.age = 0;
            this.growup()//不斷成長
            this.growEvent = {}//需要接受多個函數
        }
        setName(val){
            this.name = val
        }
        growup(){
            let _this = this;
            setInterval(()=>{
                _this.age++;
                for(let i in _this.growEvent){
                    if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                        _this.growEvent[i].forEach(cb=>{
                            if(cb instanceof Function){
                                cb.call(this)//需要註意更改this指向,不然指向window
                            }
                        })
                    }
                }
                
            },100)
        }
        addEventListener(name,cb){
            if(name && cb instanceof Function){
                if(this.growEvent[name]){
                    this.growEvent[name].push(cb)
                }else{
                    this.growEvent[name] = []
                    this.growEvent[name].push(cb)
                }
            }
        }
        
    }
    let hx = new Person()
    hx.setName(‘韓信‘)
    hx.addEventListener(‘army‘,function(){
        if(this.age == 18){
            console.log(‘開始參軍啦‘)
        }
    })
    hx.addEventListener(‘lead‘,function(){
        if(this.age == 20){
            console.log(‘當上小隊長啦‘)
        }
    })
    hx.addEventListener(‘lead‘,function(){
        if(this.age == 25){
            console.log(‘當上大隊長啦‘)
        }
    })

那麽接下來要做的是如何removeEventListener 呢?一種方式是粗暴的直接清空數組,把多個事件同時清除。

class Person{
        constructor(){
            this.name = ‘‘;
            this.age = 0;
            this.growup()//不斷成長
            this.growEvent = {}//需要接受多個函數
        }
        setName(val){
            this.name = val
        }
        growup(){
            let _this = this;
            setInterval(()=>{
                _this.age++;
                for(let i in _this.growEvent){
                    if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                        _this.growEvent[i].forEach(cb=>{
                            if(cb instanceof Function){
                                cb.call(this)//需要註意更改this指向,不然指向window
                            }
                        })
                    }
                }
                
            },100)
        }
        addEventListener(name,cb){
            if(name && cb instanceof Function){
                if(this.growEvent[name]){
                    this.growEvent[name].push(cb)
                }else{
                    this.growEvent[name] = []
                    this.growEvent[name].push(cb)
                }
            }
        }
        removeEventListener(name){
            if(name && this.growEvent.hasOwnProperty(name)){
                this.growEvent[name] = []
            }
        }
    }
    let hx = new Person()
    hx.setName(‘韓信‘)
    hx.addEventListener(‘army‘,function(){
        if(this.age == 18){
            console.log(‘開始參軍啦‘)
        }
    })
    hx.addEventListener(‘lead‘,function(){
        if(this.age == 20){
            console.log(‘當上小隊長啦‘)
        }
    })
    hx.addEventListener(‘lead‘,function(){
        if(this.age == 25){
            console.log(‘當上大隊長啦‘)
        }
    })
    hx.removeEventListener(‘army‘);

上面這樣的話,韓信就不會開始參軍了,直接當小隊長起步。

但是這樣做的話還是有點不好,包括js裏的原生事件也是,移除監聽的時候,是需要函數名稱的。具名函數無論是在回調還是遞歸裏都非常有用。

class Person{
        constructor(){
            this.name = ‘‘;
            this.age = 0;
            this.growup()//不斷成長
            this.growEvent = {}//需要接受多個函數
        }
        setName(val){
            this.name = val
        }
        growup(){
            let _this = this;
            setInterval(()=>{
                _this.age++;
                for(let i in _this.growEvent){
                    if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                        _this.growEvent[i].forEach(cb=>{
                            if(cb instanceof Function){
                                cb.call(this)//需要註意更改this指向,不然指向window
                            }
                        })
                    }
                }
                
            },100)
        }
        addEventListener(name,cb){
            if(name && cb instanceof Function){
                if(this.growEvent[name]){
                    this.growEvent[name].push(cb)
                }else{
                    this.growEvent[name] = []
                    this.growEvent[name].push(cb)
                }
            }
        }
        removeEventListener(name,cbName){
            if(name && this.growEvent.hasOwnProperty(name)){
                this.growEvent[name] = this.growEvent[name].filter(cb=>{
                    return cb != cbName
                })
            }
        }
    }
    let hx = new Person()
    hx.setName(‘韓信‘)
    hx.addEventListener(‘army‘,function(){
        if(this.age == 18){
            console.log(‘開始參軍啦‘)
        }
    })
    hx.addEventListener(‘lead‘,fn)
    function fn(){
        if(this.age == 20){
            console.log(‘當上小隊長啦‘)
        }
    }
    hx.addEventListener(‘lead‘,function(){
        if(this.age == 25){
            console.log(‘當上大隊長啦‘)
        }
    })
    hx.removeEventListener(‘lead‘,fn);

這樣的話,韓信就沒有當小隊長這個過程啦!

寫一個addEventListener以及removeEventListener