我们平常接触到的事件都是与页面的DOM元素在交互,例如下面
<button id="button">点我</button>
<script>
function $(id){
return document.getElementById(id);}
function handler(){
alert("晚上见");}
$("button").addEventListener("click",handler,false);
</script>
对于DOM这样的元素我们可以这样做,然而这让非DOM怎么想?在事件交互的世界上,就只能是DOM元素的天下?结论当然是不可能的,这天下永远不会姓李,他也有可能姓交。
var listener={};
创建一个观察者对象
function addEvent(type,fun){
If(typeof this.listener[type] =="undefined")
{ this.listener[type] = [];}
this.listener[type].push(fun);
}
添加事件:如果当前对象的内部listener属性没有参数中的type事件类型,这创建一个名为type的数组,并将参数中的fun方法,传入数组
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);}
}
};
触发事件:首先验证当前对象中有当作参数传入的type事件数组,随后循环依次执行,数组内的方法
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;}
}
}
};
移除事件,如果对象存在参数中的事件类型,且数组中存在fun方法,用splice()方法移除fun方法;
既然我们已经定义好了观察对象,以及操作观察对象的方法,那么来试一试吧。
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"});
我们为创建的person对象,定义了一个sleep事件,且事件发生是将依次执行sleep1,sleep2,sleep3方法。
删除sleep事件中的sleep3方法:
removeEvent.call(person,"sleep",sleep3);
fireEvent.call(person,{type:"sleep"});
person{
listener:{sleep:[sleep1,sleep2,sleep3]
}
上述代码仔细观察,就能了解到,我们只是往person对象中添加了listener对象,至于调用addEvent(),fireEvent(),removeEvent(),都是通过call()方法改变执行环境实现的
下面是上面几个函数的封装:
<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>