自定義事件

我們平常接觸到的事件都是與頁面的DOM元素在交互,例如下面

<button  id="button">點我</button>
<script>
function $(id){
return document.getElementById(id);}
function handler(){
    alert("晚上見");}
$("button").addEventListener("click",handler,false);
</script>

對于DOM這樣的元素我們可以這樣做,然而這讓非DOM怎么想?在事件交互的世界上,就只能是DOM元素的天下?結(jié)論當(dāng)然是不可能的,這天下永遠(yuǎn)不會姓李,他也有可能姓交。

var listener={};

創(chuàng)建一個觀察者對象

function addEvent(type,fun){
If(typeof this.listener[type] =="undefined")
{ this.listener[type] = [];}
this.listener[type].push(fun);
}

添加事件:如果當(dāng)前對象的內(nèi)部listener屬性沒有參數(shù)中的type事件類型,這創(chuàng)建一個名為type的數(shù)組,并將參數(shù)中的fun方法,傳入數(shù)組

function fireEvent(event){
if(!event.target)
    {event.target=this;}
       if(Array.isArray(this.listener[event.type])){
         var funs=this.listener[event.type];
         len=funs.length;
         for(var i=0;i<len;i++){
         funs[i](event);}                       
               }
 };

觸發(fā)事件:首先驗證當(dāng)前對象中有當(dāng)作參數(shù)傳入的type事件數(shù)組,隨后循環(huán)依次執(zhí)行,數(shù)組內(nèi)的方法

function removeEvent(type,fun){
if(Array.isArray(this.listener[type])){
var funs=this.listener[type];
len=funs.length;
for(var i=0;i<len;i++){
if(funs[i] === fun){
funs.splice(i,1)
break;} 
}
}
};

移除事件,如果對象存在參數(shù)中的事件類型,且數(shù)組中存在fun方法,用splice()方法移除fun方法;
既然我們已經(jīng)定義好了觀察對象,以及操作觀察對象的方法,那么來試一試吧。

var person=new Object();
person.listener=listener;
var sleep1=function(){
    console.log("今天睡一個");}
var sleep2=function(){
    console.log("明天睡兩個");}
var sleep3=function(){
    console.log("后天睡三個小時");}
addEvent.call(person,"sleep",sleep1);
addEvent.call(person,"sleep",sleep2);
addEvent.call(person,"sleep",sleep3);
fireEvent.call(person,{type:"sleep"});

我們?yōu)閯?chuàng)建的person對象,定義了一個sleep事件,且事件發(fā)生是將依次執(zhí)行sleep1,sleep2,sleep3方法。
刪除sleep事件中的sleep3方法:

removeEvent.call(person,"sleep",sleep3);
fireEvent.call(person,{type:"sleep"});

person{
listener:{sleep:[sleep1,sleep2,sleep3]
}
上述代碼仔細(xì)觀察,就能了解到,我們只是往person對象中添加了listener對象,至于調(diào)用addEvent(),fireEvent(),removeEvent(),都是通過call()方法改變執(zhí)行環(huán)境實現(xiàn)的

下面是上面幾個函數(shù)的封裝:

<script>
function EventTarget(){
var o=new Object();
o.listener={};
o.addEvent=function(type,fun){
if(typeof o.listener[type]=="undefined")
{ o.listener[type]=[];
 
}
o.listener[type].push(fun);
};

o.fireEvent=function(event){
if(Array.isArray(o.listener[event.type]))
{var funs=o.listener[event.type];
len=funs.length;
for(var i=0;i<len;i++){
funs[i]();
}
}
};
o.removeEvent=function(type,fun){
if(Array.isArray(o.listener[type])){
var funs=o.listener[type];
len=funs.length;
for(var i=0;i<len;i++){
if(funs[i] === fun){
     funs.splice(i,1)
     break;}
   }
  }
 };
 return o;
};
var person=new EventTarget();
var sleep1=function(){
    console.log("今天睡一個");}
var sleep2=function(){
    console.log("明天睡兩個");}
var sleep3=function(){
    console.log("后天睡三個小時");}
person.addEvent("sleep",sleep1);
person.addEvent("sleep",sleep2);
person.addEvent("sleep",sleep3);
person.fireEvent({type:"sleep"});
person.removeEvent("sleep",sleep3);
person.fireEvent({type:"sleep"});
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容