【问题标题】:Capture all the events (javascript)捕获所有事件(javascript)
【发布时间】:2014-09-06 01:16:41
【问题描述】:

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

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

问题包括:动态添加的元素、阻止传播或冒泡的事件以及动态生成的自定义事件。我想需要有一个dispatchEvent 或其他东西的原型,但我不确定。这甚至可能吗?

【问题讨论】:

  • 那么,第一个问题:为什么?你想这样做真是太好了,但也很奇怪。
  • 无论您的问题是什么需要这样做,它们都可能是更好的选择。您可以轻松处理合成事件,也可以动态创建元素(有办法检测何时创建元素)
  • 这听起来很酷。不要听那些让你失望的人。
  • 不是很有帮助,@nit。他以编程方式(而不是在控制台中)进行操作,并且他想监听所有事件,而不仅仅是某些元素

标签: javascript javascript-events


【解决方案1】:

一些活动基础知识:

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

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

我想需要有一个 dispatchEvent 或其他东西的原型设计

dispatchEvent 是一个 Event 实例的方法,它没有被指定为一个构造函数(没有要求它有一个内部的 [[Construct]] 方法),所以不实用。浏览器不需要为宿主对象实现原型继承(尽管大多数都这样做),宿主对象和方法的实现细节在很大程度上是隐藏的,所以这不是一个选项。

您可能会尝试扩展事件 API,但您确实是 should not mess with host objects

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

您还可以使用修改 DOM 的函数调度自定义事件以添加侦听器或其他任何内容。

【讨论】:

    【解决方案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。)

    您也可以以类似的方式覆盖 createEventdispatch,但同样,这将仅捕获在 JS 代码中显式创建或调度的事件。

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

    【讨论】:

      猜你喜欢
      • 2014-02-14
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 2011-08-12
      相关资源
      最近更新 更多