1、基本原理:
事件队列,即将监听程序存到一个数组中,再自定函数执行时,将添加监听数组中每个函数执行一遍。
定义一个对象专门用于存储自定义事件,定义一个方法用于注册监听,还有一个方法需要我们主动触发这个注册的监听程序,以及监听的注销。
2、观察者模式
事件是JavaScript和浏览器交互的主要途径。事件是一种叫做观察者的设计模式,这是一种创建松散耦合代码的技术。
观察者模式:由两类对象组成,主体和观察者,主体负责发布事件,观察者通过订阅这些事件来观察主体。该模式的一个重要概念是主体并不知道观察者的任何事情,也就是说即使观察者不存在,主体也可以独自存在并正常运作。而观察者知道主体,并能注册事件的回调函数。
示例:当涉及DOM时,DOM元素便是主体,事件处理代码便是观察者。
3、以下实现方法为通过对象原型封装js自定义事件,设计代码如下:
//自定义事件构造函数
function EventTarget(){
//事件处理程序数组集合
this.handlers = {};
}
//自定义事件的原型对象
EventTarget.prototype = {
//设置原型构造函数链
constructor: EventTarget,
//注册给定类型的事件处理程序,
//type -> 自定义事件类型, handler -> 自定义事件回调函数
addEvent: function(type, handler){
//判断事件处理数组是否有该类型事件
if(typeof this.handlers[type] == 'undefined'){
this.handlers[type] = [];
}
//将处理事件push到事件处理数组里面
this.handlers[type].push(handler);
},
//触发一个事件
//event -> 为一个js对象,属性中至少包含type属性,
//因为类型是必须的,其次可以传一些处理函数需要的其他变量参数。(这也是为什么要传js对象的原因)
fireEvent: function(event){
//模拟真实事件的event
if(!event.target){
event.target = this;
}
//判断是否存在该事件类型
if(this.handlers[event.type] instanceof Array){
var handlers = this.handlers[event.type];
//在同一个事件类型下的可能存在多种处理事件,找出本次需要处理的事件
for(var i = 0; i < handlers.length; i++){
//执行触发
handlers[i](event);
}
}
},
//注销事件
//type -> 自定义事件类型, handler -> 自定义事件回调函数
removeEvent: function(type, handler){
//判断是否存在该事件类型
if(this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
//在同一个事件类型下的可能存在多种处理事件
for(var i = 0; i < handlers.length; i++){
//找出本次需要处理的事件下标
if(handlers[i] == handler){
break;
}
}
//从事件处理数组里面删除
handlers.splice(i, 1);
}
}
调用方法:
function b(){
console.log(123);
}
var target = new EventTarget();
target.addEvent("eat", b);
target.fireEvent({
type: "eat"
});