检测当事件被添加到一个元素上

3

如何检测元素添加事件处理程序?

我遇到了一篇文章,其中有人使用了很多插件,其中一个插件开始通过添加事件处理程序(例如onkeypress)窃听。我想要能够监视特定元素上的事件被添加,或者在它们被添加到特定元素时检测它们。我不关心DOM本身的变化,只关心事件处理程序被添加到特定元素的操作。我也不是指HTML属性版本的事件处理程序(例如<input type="search" onkeypress="" />),而是通过addEventListener添加的事件。没有框架或库。除了作为示例的搜索输入元素之外,没有涉及任何特定项目(或相关代码)。如果需要考虑权限(例如通过iframescript元素设置的内容),请注意。


1
这是一个很好的问题,因为我使用多个处理程序和发射器在元素上,但从未能够看到元素上有多少事件处理程序。 - JonoJames
1
@JonoJames 谢谢。您的意思是通过 JavaScript 本身完成吗?虽然我不能坐在每个人的电脑旁要求检查他们的 DOM,但肯定可以通过开发人员工具轻松完成。lol - John
1个回答

1
一种可能的方法是对Element.prototype.addEventListener进行猴子补丁(实际上该属性在EventTarget.prototype.addEventListener上)。当您的自定义函数运行时,您将知道其他JS已添加了事件侦听器,并且您可以使用debuggerconsole.trace()或抛出错误来找出位置:
Element.prototype.addEventListener = function(...args) {
  const eventType = args[0];
  if (eventType === 'keypress') {
    console.log('Keypress listener was just added!');
    console.trace();
  }
  return EventTarget.prototype.addEventListener.apply(this, args);
};

Element.prototype.addEventListener = function(...args) {
  const eventType = args[0];
  if (eventType === 'keypress') {
    console.log('Keypress listener was just added!');
    console.trace();
  }
  return EventTarget.prototype.addEventListener.apply(this, args);
};

// Somewhere else, an event listener gets added:
button.onclick = () => {
  input.addEventListener('keypress', () => {
    console.log('keypress event just fired');
  });
};
<button id="button">Add a listener</button>
<input id="input">

请注意,改变内置原型几乎从来不是一个好主意——即使您认为已经做得很好,它也可能会破坏事情,特别是当脚本使用库时。虽然这种技术可以用于调试,但它不应该出现在生产代码中。
如果您只想查看附加了什么,并且实际上并不关心何时,您可以检查元素并查看它当前具有哪些事件侦听器:

enter image description here


我要试试这个!我必须添加一个投票以防止有人试图进行投票(以试图打破我的反击),并仅锁定并通知用户出现问题。现在已经很晚了,可能要等到明天才能做出恰当的回应,但这真是太有趣了。感谢您的发帖,我会在进行一些有意义的实验后回复。 :-) - John
@John 如果有人可以添加运行代码来为页面上的对象添加事件监听器,他们几乎肯定也可以覆盖 addEventListener 以防止你观察他们正在添加什么。 - jirassimok
@jirassimok 在我的代码中,我有HTML属性(是的,我知道这不被看好,但我可以处理它们),所以很少使用addEventListener。这就是为什么我提到了iframescript元素。我不知道浏览器允许设置事件的自由度,我相信这是另一个需要问的问题。感谢您的见解。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接