摘要:首先來看看什么是自定義事件讓函數(shù)能夠具備事件的某些特性。其實自定義事件在一些主流的類庫中都有實現(xiàn),后續(xù)會分析具體的實現(xiàn)方法。今天,我們就先用簡單的例子來實現(xiàn)自定義事件的功能。
在團隊協(xié)作的很多情況下,某個js的函數(shù)會根據(jù)不斷增加的需求進而不斷增加功能,如果功能需求累積過多,我們就很難把控自己在這個函數(shù)中新定義的變量會不會覆蓋掉之前的定義。如:
function action(){ console.log(1); console.log(2);//新增需求1 console.log(3);//新增需求2 ......//一直增加就很難保證下面的代碼不會與之前的代碼產(chǎn)生沖突 }
而如果我們?yōu)樾略龅男枨笾匦露x一個同名的js方法,那后來定義的方法又會將之前定義的方法覆蓋,這當(dāng)然也不是我們想要的結(jié)果。如:
function action(){console.log(1);} function action(){console.log(2);}//新增需求1 function action(){console.log(3);}//新增需求2
執(zhí)行結(jié)果:3
那么有沒有什么辦法可以讓我們的函數(shù)分別執(zhí)行,并且互不影響呢?是的,你一定想到了js事件。
說到j(luò)s的事件,我們立馬就會想到原生js中對事件的實現(xiàn)。在標(biāo)準(zhǔn)DOM瀏覽器中的addEventListener、removeEventListener和在IE中的attachEvent、detachEvent這些已經(jīng)為我們熟知,并且綁定在同一個DOM中的相同的事件彼此不會被覆蓋,比如,你在某個div中綁定了3個click事件,在執(zhí)行時它們會按序執(zhí)行,而不會只執(zhí)行最后一次綁定:
//下面的例子僅實現(xiàn)標(biāo)準(zhǔn)DOM瀏覽器 oDiv.addEventListener("click",function(){console.log(1);},false); oDiv.addEventListener("click",function(){console.log(2);},false); oDiv.addEventListener("click",function(){console.log(3);},false);
執(zhí)行結(jié)果:1 2 3
看起來剛好解決了我們的各種顧慮,多帶帶定義,互不影響,很有利于團隊協(xié)作,但是這些內(nèi)置的事件綁定方式卻依然無法直接解決我們的問題。
好吧,既然無法直接解決,那我們就利用頁面事件綁定的思想來自己探索,這就是我們今天要介紹的自定義事件。
首先來看看什么是自定義事件:讓函數(shù)能夠具備事件的某些特性。
其實自定義事件在一些主流的類庫中都有實現(xiàn),后續(xù)會分析具體的實現(xiàn)方法。今天,我們就先用簡單的例子來實現(xiàn)自定義事件的功能。
回到開始的時候我們提出的需求:讓函數(shù)分別執(zhí)行,并且互不影響。這就好像我們要按照清單從圖書館借5本書,走出圖書館的時候,我們手里拿到的應(yīng)該是想借的5本,而不是清單上的最后一本。
依照js的事件綁定方式來剖析一下這幾本書和圖書館之間的關(guān)系:
其中,圖書館就是我們要綁定事件的對象,也就是我們借書的對象,“click”就是我們綁定事件的類別,也就是我們想要借的書的分類,而function回調(diào)就是我們要執(zhí)行的函數(shù),也就是我們想借的具體某本書。理清了對應(yīng)關(guān)系,我們就可以從一個圖書館內(nèi)不同的分類書架上拿到不同的書。
把這個對應(yīng)的關(guān)系映射到自定義事件上就是:在某個對象上綁定不同類別的一個或多個方法,并且讓它們分別執(zhí)行。接下來我們就來實現(xiàn)一下這種關(guān)系。首先來看一下自定義事件的綁定實現(xiàn):
//綁定 function on(obj,events,fn){//參數(shù)分別是:對象/自定義事件類別/方法 //初始化自定義監(jiān)聽對象,如果存在繼續(xù)使用,不存在就創(chuàng)建新對象 obj.listeners = obj.listeners || {}; obj.listeners[events] = obj.listeners[events] || [];//初始化監(jiān)聽的自定義事件列表 obj.listeners[events].push(fn);//將要執(zhí)行的方法分別存放到對應(yīng)事件的列表中 }
這樣,我們就把想要執(zhí)行的一系列方法綁定到了某個頁面對象對應(yīng)的自定義事件類別上。方法綁定好了之后,如何去觸發(fā)呢?看下面的代碼實現(xiàn):
//觸發(fā) function fire(obj,events){//參數(shù)分別是:對象/自定義事件類別 for(var i = 0; i < obj.listeners[events].length; i++){//遍歷某個事件類別下所有的方法 obj.listeners[events][i]();//依次執(zhí)行遍歷到的所有的方法 } }
這樣,我們定義的想要去執(zhí)行的每個方法都能被執(zhí)行,并且它們之間互不影響??磦€實際的例子:
var eventHandle = { on: function(obj,events,fn){ obj.listeners = obj.listeners || {}; obj.listeners[events] = obj.listeners[events] || []; obj.listeners[events].push(fn); }, fire: function(obj,events){ for(var i = 0, n = obj.listeners[events].length; i < n; i++){ console.log(obj.listeners[events]); obj.listeners[events][i] && obj.listeners[events][i](); } }, off: function(obj,events){ for(var i = 0, n = obj.listeners[events].length; i < n; i++){ obj.listeners[events][i] = null; } } }; //綁定自定義事件, eventHandle.on(oDiv,"eventType1",function(){console.log(1);});//準(zhǔn)備執(zhí)行方法1 eventHandle.on(oDiv,"eventType1",function(){console.log(2);});//準(zhǔn)備執(zhí)行方法2 eventHandle.on(oDiv,"eventType1",function(){console.log(3);});//準(zhǔn)備執(zhí)行方法3 eventHandle.on(oDiv,"eventType2",function(){console.log(4);});//準(zhǔn)備執(zhí)行方法4 //觸發(fā)執(zhí)行 eventHandle.fire(oDiv,"eventType1");//執(zhí)行eventType1下的所有方法
執(zhí)行結(jié)果:1 2 3
不執(zhí)行方法4是因為,eventType2下的方法4僅僅被綁定,并沒有被觸發(fā)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86165.html
摘要:它有發(fā)布者,訂閱者這兩個主要對象。的最佳實踐就是通過反射犧牲了微小的性能,同時極大的降低了程序的耦合度。官網(wǎng)和應(yīng)用場景框架的主要功能是幫助我們來降低多個組件通信之間的耦合度的解耦。 前兩天在公眾號里發(fā)了一篇有關(guān)EventBus的文章《玩轉(zhuǎn)EventBus,詳解其使用》,有讀者和開發(fā)者反饋說沒有OTTO好用。確實是,各有優(yōu)缺點吧,那今天就有必要再講一下Otto事件框架。 OTTO是Squ...
摘要:調(diào)用棧是一種棧結(jié)構(gòu)它用來存儲計算機程序執(zhí)行時候其活躍子程序的信息。調(diào)用棧是解析器的一種機制。并形成一個棧幀任何被這個函數(shù)調(diào)用的函數(shù)會進一步添加到調(diào)用棧中,形成另一個棧幀并且運行到它們被上個程序調(diào)用的位置。然后調(diào)用棧繼續(xù)運行其他部門。 大家在進行javascript開發(fā)的時候,有沒有想過,我們寫的代碼是怎么樣運行的呢?下面我們就來剖析一下代碼的執(zhí)行過程。 一 什么是調(diào)用棧 代碼在運行過程...
閱讀 1996·2021-09-07 10:24
閱讀 2096·2019-08-30 15:55
閱讀 2049·2019-08-30 15:43
閱讀 674·2019-08-29 15:25
閱讀 1063·2019-08-29 12:19
閱讀 1948·2019-08-23 18:32
閱讀 1523·2019-08-23 17:59
閱讀 954·2019-08-23 12:22