在 JavaScript 中捕获所有事件

问题描述 投票:0回答:2

我希望能够捕获所有创建和调度的事件,并在发生这种情况时触发一些回调。

此外,我希望能够在事件与事件侦听器配对时随时触发回调。

问题包括:动态添加的元素、阻止传播或冒泡的事件、动态生成的自定义事件。我想可能需要制作

dispatchEvent
之类的原型,但我不确定。这甚至可能吗?

javascript dom-events
2个回答
5
投票

一些活动基础知识:

  1. 事件在作为事件目标的 DOM 对象(通常是一个元素)“上”调度。
  2. 事件可以首先向下传播到捕获阶段的子元素。这个阶段很少使用,因为它直到最近才被一些广泛使用的浏览器支持。
  3. 事件可以在冒泡阶段传播到父元素。这个阶段很常用。
  4. 有些事件不会传播,它们既没有捕获阶段也没有冒泡阶段(例如聚焦、模糊和提交事件)。在某些浏览器中传播的某些事件不会在其他浏览器中传播。
  5. 响应事件的 DOM 元素有一个事件处理程序。它可以设置为侦听特定事件并在该事件到达元素时调用侦听器函数,无论是在捕获、冒泡期间还是元素是事件目标时。
  6. Listeners 可以取消传播,例如链接内 span 上的点击事件可以取消传播,因此链接不会获得点击

鉴于上述情况,使用Events API“捕获所有事件”实际上是不可能的。这将需要为每个元素上的每个事件类型建立一个监听器,并且不可能捕获自定义事件,因为您必须了解它们才能设置合适的监听器。

我想需要有一个 dispatchEvent 之类的原型设计

dispatchEvent 是一个 Event 实例的方法,它没有被指定为构造函数(不需要它有一个内部的

[[Construct]]
方法)所以这样使用不切实际。浏览器不需要为宿主对象实现原型继承(尽管大多数都这样做),并且宿主对象和方法的实现细节在很大程度上是隐藏的,所以这不是一个选项。

您可以尝试扩展事件 API,但您真的不应该弄乱宿主对象.

看来你关心的是动态添加的元素。有一种称为事件委托的策略,您可以在其中计算出需要侦听的事件,然后在不更改的元素(例如表格)上设置尽可能接近事件目标的侦听器元素,如果您动态添加和删除表行,或其他元素的容器 div)对于您需要响应的特定事件类型。

您还可以让修改 DOM 的函数派发自定义事件以添加侦听器或其他任何东西。


3
投票

如果你真的想这样做,那么你可以覆盖

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 代码中明确创建或调度的事件。

如果你真的想做你似乎想做的事,我想你需要 fork Chrome。

© www.soinside.com 2019 - 2024. All rights reserved.