1 // 要利用观察者模式 去实现自定义的事件
2
3
4 //1:由于浏览器他自己能定义内置的事件(click/blur...)
5 // 我们也应该有一个类似于浏览器这样的类,这个类 自己去内部定义一些事件(自定义事件)
6 var Observable = function(){
7 //承装自己所定义的事件类型的
8 this.events = ['start','stop'];
9 //我们应该设计一种数据类型,这种数据类型就可以去维护自定义事件类型 和 和相关绑定函数的关系,结构如下所示:
10 // 'start':[fn1 ,fn2....] ,
11 // 'stop':[fn1,fn2]
12 this.listeners = {
13
14 };
15 };
16
17 //2:添加新的自定义事件类型:
18 Observable.prototype.addEvents = function(eventname){
19 this.events.push(eventname);
20 };
21
22
23 //3:为自己的事件类型绑定响应的函数(添加事件监听)
24 Observable.prototype.addListener = function(eventname,fn){
25 //做一个容错的处理
26 if(this.events.indexOf(eventname) == -1){
27 this.addEvents(eventname);
28 }
29 //到这一步 ,必然存在这个事件类型了
30 var arr = this.listeners[eventname];
31 //如果当前这个函数数组不存在,那么我们要为这个事件类型绑定新添加的函数
32 if(!arr){
33 arr = [fn];
34 } else { //如果存在 当前这个事件类型所对应的函数的数组不为空
35 if(arr.indexOf(fn) == -1){
36 arr.push(fn);
37 }
38 }
39 //重新维护一下事件类型 和所绑定的函数数组的关联关系
40 this.listeners[eventname] = arr ;
41 };
42
43 //4:移除事件监听
44 Observable.prototype.removeListener = function(eventname,fn){
45 //如果你要移除的事件类型,在我的对象里没有被定义
46 if(this.events.indexOf(eventname) == -1){
47 return ;
48 }
49 //到这一步 就是你要移除的事件类型 是我当前对象里面存在的
50 var arr = this.listeners[eventname];
51 if(!arr){
52 return ;
53 }
54 //到这一步 证明arr里面是有绑定函数的
55 //判断 如果当前fn函数 在我的函数数组里存着 就移除
56 if(arr.indexOf(fn) != -1){
57 arr.splice(arr.indexOf(fn),1);
58 }
59 };
60
61 //5:如何让事件触发: 就是调用 这个事件类型所对应的所有的函数执行即可
62 Observable.prototype.fireEvent = function(eventname){
63 //如果当前没有传递事件类型名称或者当前传递的事件类型不存在我的对象里,直接返回
64 if(!eventname || (this.events.indexOf(eventname) == -1)){
65 return ;
66 }
67 //到这一步 一定存在这个事件
68 var arr = this.listeners[eventname];
69 if(!arr){
70 return ;
71 }
72 for(var i = 0 , len = arr.length ; i < len ; i ++){
73 var fn = arr[i];
74 fn.call(fn,this);
75 }
76 };
77
78 //javascript的习惯 给原型对象的方法 起一个简单的名字 方便开发者去使用
79 Observable.prototype.on = Observable.prototype.addListener;
80 Observable.prototype.un = Observable.prototype.removeListener;
81 Observable.prototype.fr = Observable.prototype.fireEvent;
82
83
84
85 //Observable 浏览器:
86 var ob = new Observable(); //被观察者
87 // 子类 继承Observable //观察者
88 var fn1 = function(){
89 alert('fn1....');
90 };
91 ob.on('start',fn1);
92
93 var fn2 = function(){
94 alert('fn2....');
95 };
96 ob.on('start',fn2);
97
98 //移除监听
99 ob.un('start',fn1);
100 ob.fr('start');
101 //ob.fr('stop');
102
103 ob.on('run',function(){
104 alert('run....');
105 });
106 ob.fr('run');
107
108
109
110 //Ext.util.Observable 类 是为了为开发者提供一个自定义事件的接口
111 //Ext.util.Observable
112 //观察者模式:(报社、订阅者) 被观察者、观察者
113 //Ext.util.Observable 被观察者
114 //所有继承(混入)Ext.util.Observable类的对象(子类) 观察者
115
116
117
118
119
120
121
122
123
124