【发布时间】:2012-03-11 05:32:32
【问题描述】:
我创建了一个多用途工厂事件发射器工厂函数。有了它,我可以将对象变成事件发射器。如果有人想看看或使用它,下面是事件发射器工厂的代码。
我的问题是如何从 DOM 中获取事件列表。 请注意,我不是要获取绑定事件的列表。我想要一个所有可能事件的列表。我想向发射器添加一个“管道”方法。此方法将获取一个 DOM 对象并绑定到所有可能的事件,然后当这些事件中的任何一个触发时,每个事件都会在发射器中触发一个同名事件。
我不认为有办法做到这一点。我准备制作一个硬编码的事件名称数组,但是如果我可以获取 DOM 的数组,那会更好,并且如果 W3C 标准化更多事件类型,它仍然可以工作。
附:如果你为 W3C 工作,这是一种让每个人都讨厌 DOM 的废话。请停止将 JavaScript 视为玩具语言。它不是一种玩具语言,它需要的不仅仅是玩具 DOM。
/**
* Creates a event emitter
*/
function EventEmitter() {
var api, callbacks;
//vars
api = {
"on": on,
"trigger": trigger
};
callbacks = {};
//return the api
return api;
/**
* Binds functions to events
* @param event
* @param callback
*/
function on(event, callback) {
var api;
if(typeof event !== 'string') { throw new Error('Cannot bind to event emitter. The passed event is not a string.'); }
if(typeof callback !== 'function') { throw new Error('Cannot bind to event emitter. The passed callback is not a function.'); }
//return the api
api = {
"clear": clear
};
//create the event namespace if it doesn't exist
if(!callbacks[event]) { callbacks[event] = []; }
//save the callback
callbacks[event].push(callback);
//return the api
return api;
function clear() {
var i;
if(callbacks[event]) {
i = callbacks[event].indexOf(callback);
callbacks[event].splice(i, 1);
if(callbacks[event].length < 1) {
delete callbacks[event];
}
return true;
}
return false;
}
}
/**
* Triggers a given event and optionally passes its handlers all additional parameters
* @param event
*/
function trigger(event ) {
var args;
if(typeof event !== 'string' && !Array.isArray(event)) { throw new Error('Cannot bind to event emitter. The passed event is not a string or an array.'); }
//get the arguments
args = Array.prototype.slice.apply(arguments).splice(1);
//handle event arrays
if(Array.isArray(event)) {
//for each event in the event array self invoke passing the arguments array
event.forEach(function(event) {
//add the event name to the begining of the arguments array
args.unshift(event);
//trigger the event
trigger.apply(this, args);
//shift off the event name
args.shift();
});
return;
}
//if the event has callbacks then execute them
if(callbacks[event]) {
//fire the callbacks
callbacks[event].forEach(function(callback) { callback.apply(this, args); });
}
}
}
【问题讨论】:
-
这听起来很像我上个世纪的旧离散事件模型。由于 Firefox & Co 在 2K 之后不久在 IE 上的肮脏战争,我不得不将其关闭,因为动态构建所有支持的事件列表只能在 MSIE 上进行。我使用“at”而不是内置的“on”来区分事件模型。离散主要是因为它不会冒泡......
标签: javascript dom event-handling dom-events