寫一個addEventListener以及removeEventListener
阿新 • • 發佈:2018-08-04
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