javascript
javascript自定义事件原理
我們都知道,鼠標(biāo)點(diǎn)擊click,觸屏的touch等事件,可以觸發(fā)相應(yīng)的事件處理程序,也可以為這些事件添加事件處理程序,實(shí)際開發(fā)過程中可供我們使用的事件很少,click、doubleclick,mouseover、mousemove….等等這些。但當(dāng)我們的程序越來越復(fù)雜的時(shí)候,光靠這些最底層的監(jiān)聽似乎已近不能滿足我們的需求了。我們就需要我們自己去定義事件(其實(shí)就是我們寫的函數(shù)),尤其是組件開發(fā)過程中,用的尤為多。
既然是事件,就要有事件的特性。我們要能為這個(gè)事件添加監(jiān)聽程序,這個(gè)事件觸發(fā)時(shí),監(jiān)聽程序也一定要觸發(fā)才行。原理跟底層的事件類似。只不過,需要我們自己處理這些。
比如我們寫了一個(gè)彈窗組件Box,他有彈出顯示的方法show,還有關(guān)閉的方法close等。
可能有確定按鈕、取消按鈕等操作。隨著產(chǎn)品或項(xiàng)目越復(fù)雜,被添加到這些確定或取消的操作也會(huì)越來越多。怎么辦?一種是最原始的監(jiān)聽這些按鈕的click事件,然后的寫不同的回調(diào)。但是用回調(diào)的方式,有個(gè)弊端,當(dāng)項(xiàng)目需求改變的時(shí)候,要往這個(gè)按鈕上再另加個(gè)回調(diào)的時(shí)候,就要改原先的代碼,要是以后再來一次,又要改。維護(hù)成本相當(dāng)大。
我們不妨換個(gè)思路,把這個(gè)‘確定’或‘取消’想成像click這樣的事件,當(dāng)‘確定‘這個(gè)事件發(fā)生時(shí)其相應(yīng)的一系列事件都會(huì)發(fā)生。就可以很好的解決這個(gè)問題。
基本原理:事件隊(duì)列,即將監(jiān)聽程序存到一個(gè)數(shù)組中,再自定函數(shù)執(zhí)行時(shí),將添加監(jiān)聽數(shù)組中每個(gè)函數(shù)執(zhí)行一遍。
定義一個(gè)對(duì)象專門用于存儲(chǔ)自定義事件,定義一個(gè)方法用于注冊(cè)監(jiān)聽,還有一個(gè)方法需要我們主動(dòng)觸發(fā)這個(gè)注冊(cè)的監(jiān)聽程序(因?yàn)椴幌馽lick等事件可以被瀏覽器監(jiān)聽捕獲,瀏覽器無法識(shí)別我們自己定義的東西)。
代碼如下:
//定義一個(gè)Box類 function Box(){//other codethis.handlers = {};//存儲(chǔ)事件的對(duì)象 } Box.prototype = {constructor: Box,//顯示方法show: function (){//code//this.fire('show');},//關(guān)閉方法close: function (){//code//this.fire('close');},//監(jiān)聽方法,模擬addEventListener,其中type為事件函數(shù),handler為需要觸發(fā)的函數(shù)。addListener: function (type,handler){ if (typeof this.handlers[type] == 'undefined')this.handlers[type] = []; this.handlers[type].push(handler);//將要觸發(fā)的函數(shù)壓入事件函數(shù)命名的數(shù)組中},//手動(dòng)觸發(fā)方法fire: function (type){if ( this.handlers[type] instanceof Array ){var handlers = this.handlers[type];//遍歷事件函數(shù)監(jiān)聽的程序,依次執(zhí)行for (var i=0;i<handlers.length;i++){handlers[i]();}}},//事件解綁removeListener: function (type,handler){if (!this.handlers[type]) return;var handlers = this.handlers[type];if (handler == undefined){handlers.length = 0;//不傳某個(gè)具體函數(shù)時(shí),解綁所有}else if( handlers.length ){ for ( var i=0;i<handlers.length;i++ ){if ( handlers[i] == handler ){//解綁單個(gè)this.handlers[type].splice(i,1);}}}} }剩下就是在需要的的時(shí)候添加注冊(cè)監(jiān)聽了,比如
var box = new Box(); function listenShow1(){console.log(11); } function listenShow2(){console.log(22); } box.addListener('show',listenShow1); box.addListener('show',listenShow2); box.show();當(dāng)show方法執(zhí)行,在外部或者show方法內(nèi)部執(zhí)行,這個(gè)可能根據(jù)實(shí)際具體項(xiàng)目或這具體情況來確定。
當(dāng)然以上只是基本原理,可能沒有特別考慮更為復(fù)雜或具體的實(shí)際情況。比如解綁是只想解綁某一類,像jQuery那樣,在事件身上加命名空間,解綁該命名空間上的所有函數(shù)。但是自定義事件的基本原理就是如上描繪的那樣!
總結(jié)
以上是生活随笔為你收集整理的javascript自定义事件原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【原】Java学习笔记028 - 集合
- 下一篇: [JS] 动态修改ckPlayer播放器