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