事件是一种叫做观察者的设计模式,这是一种创建松散耦合的技术。观察者模式由两类对象组成:主体和观察者。主体负责发布事件。同时观察者通过订阅这些事件来观察该主体。该模式的一个关键概念是主体并不知道观察者的任何事情,也就是说它可以独自存在并正常运作即使观察者不存在。从另一方面来说。观察者知道主体并能注册事件的回调函数(事件处理程序),涉及到Dom上时,Dom元素便是主体,你的事件处理代码便是观察者。
事件是与Dom交互的最常见的方式,但它们也可以用于非Dom代码中--通过实现自定义事件。
自定义事件背后的概念是创建一个管理事件的对象。让其他对象监听那些事件。实现此功能的基本模式可以定义如下:
function EventTarget(name1) {
this.name = name1;
this.handlers = {}
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type, handler) {
console.log(type);
//刚开始只有type并没有为this.handlers[type]赋值
if (typeof this.handlers[type] == "undefined") {
this.handlers[type] = [];
console.log("hi")
}
//接着执行push
this.handlers[type].push(handler);
console.log(this.handlers[type]);
},
fire: function(event) {
if (!event.target) {
event.target = this;
console.log("not have eventTarget")
}
if (this.handlers[event.type] instanceof Array) {
console.log("isArray")
var handlers = this.handlers[event.type];
//循环执行多个事件
for (var i = 0, len = handlers.length; i < len; i++) {
handlers[i](event);
}
}
},
removeHandler: function(type, handler) {
if (this.handlers[type] instanceof Array) {
var handlers = this.handlers[type];
for (var i = 0, len = handlers.length; i < len; i++) {
if (handlers[i] === handler) {
break;
}
}
handlers.splice(i, 1);
}
console.log(handlers);
}
}
然后使用EventTarget类型的自定义事件:
function handleMessage(event) {
alert("Message received:" + event.message);
}
//创建一个新对象
var target = new EventTarget()
//添加一个事件处理程序
target.addHandler("message",handleMessage)
//触发事件
target.fire({type:"message",message:"Hello World"})
//删除事件处理程序
target.removeHandler("message",handleMessage);
//触发事件不会执行
target.fire({type:"message",message:"Hello Worldmmm"})
在这段代码中,定义了handleMessage()函数用于处理message事件。它接受event对象并输出message属性。调用target对象的addHandler()方法并传给"message"以及hadleMessage()函数。在接下来的一行,调用了fire()函数,并传给了2个属性,即type和message的对象。然后删除了事件处理程序,这样即使事件再次出发,也不会显示任何警告框。
因为这种功能是封装在一种自定义类型中的,其它对象可以继承EventTarget并获得这个行为
function Person(name) {
this.name = name;
this.etarget = new EventTarget(this.name)
}
Person.prototype = {
constructor: Person,
addMessage: function(type, fn) {
this.etarget.addHandler(type, fn)
},
say: function(message) {
this.etarget.fire({ type: "message", message: message })
console.log(this.name)
}
}
function handleMessage(event) {
console.log(event)
//弹出NICHOLAS--SAYS:hi there
alert(event.target.name + "---says:" + event.message);
}
//创建新Person实例
var person = new Person("NICHOLAS");
person.addMessage("message", handleMessage);
person.say("hi there")