在类对象中如何优雅地编写事件处理器(第3版)
2019-07-14 本文已影响3人
铁甲万能狗
如前文《在类对象中如何优雅地编写进行事件处理器》对EventManager类做了些精简
class EventList {
constructor() {
this.eventMap = {};
}
/**
* 加入事件队列
* @param elem 元素
* @param eventName 事件名称
* @param fname 回调函数名称
* @param callback 回调函数的引用
* @param args 回调函数的参数
*/
put(elem, eventName, fname, callback, args) {
if (this.eventMap.hasOwnProperty(eventName)) {
let entry = {
dom: elem,
name: fname,
ref: callback,
args: args,
used: 0
}
this.eventMap[eventName].push(entry);
}
}
/**
*弹出事件队列
* @param elem 目标元素
* @param eventName 事件名称
* @param fname 事件处理器名称
* @returns {null|ref} 返回队列中的附加处理函数的引用
*/
pop(elem, eventName, fname) {
let ref = null;
if (this.eventMap.hasOwnProperty(eventName)) {
const list = this.eventMap[eventName];
for (let i = 0; i < list.length; i++) {
let entry = list[i];
if (elem == entry.dom && fname == entry.name) {
ref = entry.ref;
list.splice(i, 1);
i--;
}
}
}
return ref;
}
}
class EventManager {
constructor() {
this.evtList = new EventList();
}
/**
* 改版后的listen方法
* @param elem 目标元素
* @param event 事件名称
* @param handler 处理器函数
* @param args 处理器函数的参数
*/
listen(elem, event, handler, args = []) {
if (typeof (handler) == 'function') {
let fName = handler.name;
let callback = (elem => (handler.bind(this))(elem,...args));
elem.addEventListener(event, callback);
// elem.on(types, callback);
const hasPty = this.evtList.eventMap.hasOwnProperty(event);
if (this.evtList.eventMap[event] === undefined || hasPty === false) {
this.evtList.eventMap[event] = [];
}
this.evtList.put(elem, event, fName, callback, args);
}
}
/**
*事件处理函数注销
* @param elem 目标元素
* @param handler 处理器函数的名称
*/
revoke(event, handler) {
const elem = event.target;
let callback = this.evtList.pop(elem, event.type, handler);
if (callback != null) {
elem.removeEventListener(event.type, callback);
}
}