事件模型
发起方
指事件是由谁产生的;比如,你喊谁谁谁回家吃饭,这时候你就是发起方; 监听方
指事件是由谁来响应的,可以是一个,也可以是多个;比如,谁谁谁听到喊他回家吃饭,然后马上就回来了;

设计事件对象
- 添加监听方
- 删除监听方
- 清空监听方
- 触发监听方响应事件
JS实现模型
实现事件
在下面的函数中,向test中传递一个fn函数,将此函数作为参数进行传递;
如果之前用过c#的事件委托机制的话,就很容易理解下面这种写法了。
function test(a,b,fn){
if(typeof(fn) == "function"){
fn(a,b);
}
}
test(1,2,function(a,b){
alert(a + b); //3
});
设计一个事件对象的概念模型
基于我们上面描述的模型概念,已经JS方法基础,我们可以使用如下JS设计一个简单的事件对象模型:
function myEvent(){
this.listeners = []; //监听者列表
}
//添加一个监听者
myEvent.prototype.addListener = function(fn){
this.listeners.push(fn);
};
//除移一个监听者
myEvent.prototype.removeListener = function(fn){
var index = this.listeners.indexOf(fn);
this.listeners.splice(index,0);
};
//清除所有监听者
myEvent.prototype.clearListeners = function(){
this.listeners = [];
};
//发出执行信号,并告之所有监听者
myEvent.prototype.raise = function(e){
var l = this.listeners.length;
for(var i = 0; i < l; i++){
this.listeners[i](e); //执行所有监听方法
}
};
var me = new myEvent();
me.addListener(function(e){
document.write("我是第一个监听者 : " + e);
});
me.addListener(function(e){
document.write("<br/>我是第二个监听者 : " + e);
});
me.raise("a");
根据上面的模型设计一个现实模型
function myEvent(){
this.listeners = []; //监听者列表
}
//添加一个监听者
myEvent.prototype.addListener = function(fn){
this.listeners.push(fn);
};
//除移一个监听者
myEvent.prototype.removeListener = function(fn){
var index = this.listeners.indexOf(fn);
this.listeners.splice(index,0);
};
//清除所有监听者
myEvent.prototype.clearListeners = function(){
this.listeners = [];
};
//发出执行信号,并告之所有监听者
myEvent.prototype.raise = function(e){
var l = this.listeners.length;
for(var i = 0; i < l; i++){
this.listeners[i](e); //执行所有监听方法
}
};
function worker(name){
this.name = name;
this.boss = null;
this.startWorkEvent = new myEvent(); //定义一个startWork事件
}
worker.prototype.startWork = function(){
this.startWorkEvent.raise(this); //发起开始工作的事件,并通知外部自己的姓名
};
function boss(name){
this.name = name;
this.workers = [];
this.workerState = {}; //定义一个JS原始对象用于存放员工工作状态
}
//员工开始工作的监听者,对开始工作的员工进行状态记录
boss.prototype.onWorkerStartWork = function(worker){
worker.boss.workerState[worker.name] = true;
};
boss.prototype.addWorker = function(worker){
this.workers.push(worker);
worker.boss = this;
worker.startWorkEvent.addListener(this.onWorkerStartWork);
};
//统计
boss.prototype.summary = function(){
for(var i = 0;i<this.workers.length;i++){
//循环所有员工
var worker = this.workers[i];
if(this.workerState[worker.name]){
document.write(worker.name + "正在工作<br/>");
}
else{
document.write(worker.name + "不在工作<br/>");
}
}
};
var jim = new worker("jim");
var tom = new worker("tom");
var bob = new boss("bob");
bob.addWorker(jim);
bob.addWorker(tom);
jim.startWork();
bob.summary(); //jim正在工作 tom不在工作
潜规则
- 对于简单的事件(不需要添加多个监听者的),往往用on开头表示,下一个单词首字母大写,比如onSelect,onChange等
function worker(){
this.onWork = null;
}
worker.prototype.startWork = function(){
if(typeof(this.onWork) == "function"){
this.onWork(this);
}
};
var w = new worker();
w.onWork = function(){
document.write("start!");
};
w.startWork(); //start!
- 对于能够添加多个监听者的,往往用addEventListener(str,fn)表示,str表示事件名称,名称中一带不包含on,且首字母小写。fn表示监听者方法的具体内容。jQuery设计模式下,可以用bind来替代addEventListener,参数相同.
var btn = $("#btnLogin");
btn.bind("click",function(){
//some code here
});