我們平常接觸到的事件都是與頁面的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>