我希望能够捕获所有创建和调度的事件,并在发生这种情况时触发一些回调。
此外,我希望能够在事件与事件监听器配对时随时触发回调。
问题包括:动态添加的元素,阻止传播或冒泡的事件以及动态生成的自定义事件。我想有必要对dispatchEvent
或其他东西进行原型设计,但我不确定。这甚至可能吗?
答案 0 :(得分:3)
一些事件基础知识:
鉴于上述情况,使用Events API“捕获所有事件”实际上是不可能的。它需要为每个元素的每个事件类型建立一个监听器,并且不可能捕获自定义事件,因为你必须知道它们才能设置一个合适的监听器。
我想有必要对 dispatchEvent 或其他东西进行原型设计
dispatchEvent是一个Event实例的方法,它没有被指定为构造函数(没有要求它有一个内部[[Construct]]
方法)因此不实用。浏览器不需要为宿主对象实现原型继承(尽管大多数都是这样),并且宿主对象和方法的实现细节在很大程度上是隐藏的,所以这不是一个选项。
您可以尝试扩展Event API,但您确实should not mess with host objects。
您似乎关注动态添加的元素。有一个名为"event delegation"的策略,您可以在其中计算出需要监听的事件,然后将侦听器设置为尽可能接近事件目标,而不是更改的元素(例如,如果你是一个表元素)为您需要响应的特定事件类型动态添加和删除表行或其他元素的容器div。
您还可以使用修改DOM调度自定义事件的函数来添加侦听器或其他任何内容。
答案 1 :(得分:2)
如果您真的想这样做,那么您可以覆盖addEventListener
以跟踪正在注册和触发的事件。
var myEventManager = (function() {
var old = EventTarget.prototype.addEventListener,
listeners = [],
events = [];
EventTarget.prototype.addEventListener = function(type, listener) {
function new_listener(listener) {
return function(e) {
events.push(e); // remember event
return listener.call(this, e); // call original listener
};
}
listeners.push([type, listener]); // remember call
return old.call(this, type, new_listener(listener)); // call original
};
return {
get_events: function() { return events; },
get_listeners: function() {return listeners; }
};
}());
但是,有不可原谅的理由不这样做,尤其是当您记录数千个事件(如鼠标移动)时,您将很快耗尽内存。这也不会捕获以elt.onclick
等方式设置的事件侦听器。它当然也不会捕获通过旧的IE attachEvent
API设置的监听器。最重要的是,在内部生成和监听的事件(例如鼠标单击复选框)对您没有帮助。 (完整的解决方案还需要处理removeEventListener
。)
您也可以以类似的方式覆盖createEvent
和dispatch
,但同样只会捕获在JS代码中显式创建或分派的事件。
如果你真的想做你想做的事,我想你需要分叉Chrome。