观察者模式由两类对象组成:主体和观察者。
- 主体负责发布事件,
- 观察者负责订阅这些事件来观察主体。
关键概念:主体不知道观察者的任何事情。
- 即主体可以独立运作即使观察者不存在,观察者知道主体并能注册事件的回调函数(事件处理程序)。
DOM上,DOM元素便是主体,事件处理代码便是观察者。
自定义事件: 创建一个管理事件的对象,让其他对象监听那些事件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39function EventTarget(){
this.handlers={};
}
EventTarget.prototype={
constructor:EventTarget,
addHandler:function(type,handler){
if(typeof this.handlers[type]=="undefined"){
this.handlers[type]=[];
}
this.handlers[type].push(handler);
},
fire:function(event){
if(!event.target){
event.target=this;
}
if(this.handlers[event.type] instanceof Array){
var handlers=this.handlers[event.type];
for(var i=0,len=handlers.length;i<len;i++){
handlers[i](event);
}
}
},
removeHandler:function(type,handler){
if(this.handlers[type] instanceof Array){
var handlers=this.handlers[type];
for(var i=0,len=handlers.length;i<len;i++){
if(handlers[i]===handler){
break;
}
}
handlers.splice(i,1);
}
}
};代码解释:
- EventTarget类型有一个单独属性handlers,用于储存事件处理程序。
addHandler()
,用来注册给定类型事件的事件处理程序,接受两个参数:事件类型和用于处理该事件的函数(回调函数)- fire,用来触发一个事件,接受一个单独参数,是一个至少包含type属性的对象。
removeHandler()
,用来注销某个事件类型的事件处理程序,接受和addHandler()
一样的参数。
1 | 使用 |
- 任何对象可以继承EventTarget,使用寄生组合继承,如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25function Person(name,age){
EventTarget.call(this);
this.name=name;
this.age=age;
}
inheritPrototype(Person,EventTarget);
Person.prototype.say=function(message){
this.fire({type:"message",message:"message"});
};
//使用
function handlerMessage(event){
alert(event.target.name+'says:'+event.message);
}
//创建新person
var person=new Person('li',29);
//添加一个事件处理程序
person.addHandler('message',handlerMessage);
//在该对象上调用1个方法,它触发消息事件
person.say('Hi there.');