JS事件模型

事件模型

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

设计事件对象

  • 添加监听方
  • 删除监听方
  • 清空监听方
  • 触发监听方响应事件

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
    });
上一篇:ASP.NET MVC 音乐商店 - 5 通过支架创建编辑表单 续


下一篇:社交系统ThinkSNS+ V2.2.7版本更新播报