1 +function(w) { 2 function Evt() { 3 return new Evt.prototype.init(); 4 } 5 Evt.prototype = { 6 constructor: this, 7 init: function() { 8 this.handlers = {} 9 return this; 10 }, 11 add: function(type, fn) { 12 if(typeof type === 'string' && !(type in this.handlers)) { 13 this.handlers[type] = []; //创建一个事件集 14 } 15 if(typeof fn === 'function') { 16 this.handlers[type].push(fn); //为当前事件注册函数 17 } else { 18 throw 'the method of argument not a function' 19 } 20 return this; 21 }, 22 fire: function(type) { 23 var arrevt = []; 24 var args = []; 25 if(arguments.length > 2) { 26 args = Array.prototype.slice.apply(arguments, [1]); //获取事件参数 27 }else if(arguments.length > 1) { 28 args = arguments[1]; 29 } 30 if(typeof type === 'string' && (type in this.handlers)) { 31 arrevt = this.handlers[type]; 32 } 33 for(var i = 0, len = arrevt.length; i < len; i++) { 34 if(args.length > 0) { 35 //这里本想让事件触发扔到异步队列中去,然而却访问不到i了, 36 //于是这种操作被我弄得无意义了
//这里可以改用forEach写法,反正原理一样
37 +function(i) { 38 setTimeout(function() { 39 arrevt[i](args); 40 }, 0); 41 }(i); 42 }else { 43 +function(i) { 44 setTimeout(function() { 45 arrevt[i](); 46 }, 0); 47 }(i); 48 } 49 50 } 51 return this; 52 }, 53 del: function(type, fn) { 54 if(typeof type === 'string' && (type in this.handlers)) { 55 if(typeof fn === 'function') { 56 var arrevt = this.handlers[type]; 57 for(var i = 0, len = arrevt.length; i < len; i++) { 58 if(fn === arrevt[i]) { 59 arrevt.splite(i, 1); //删除该注册函数 60 break; 61 } 62 } 63 } 64 } 65 return this; 66 } 67 } 68 Evt.prototype.init.prototype = Evt.prototype; 69 70 window.evt = new Evt; 71 }(window);
以上代码将实现一个简单的pub/sub模式,一切皆事件,任何行为都是事件,使用方法
//将所要注册的方法交于一个类统一管理, 这里称为接口inf, //这种写法略显"浮肿",但可通过bind创建函数并改变内部this指向 var inf = { test: function(data) { console.log(data); } } //外部注册事件,并调用事件 传参仅支持数组或者对象 evt.add('test', inf.test).fire('test', 'hello, world');
浙公网安备 33010602011771号