如何在JavaScript中拦截事件处理器?重写addEventListener实现日志与原逻辑
问题
假设我有一个仅包含以下小型JS文件的简单网页:
document.addEventListener('click', (event) => { console.log("click event fired"); }); document.addEventListener('keypress', (event) => { console.log("keypress event fired"); });
需要通过Firefox开发者控制台完成以下操作:
- 重写
addEventListener函数,记录其监听的事件类型; - 完成日志记录后执行原函数逻辑。
目前已编写了如下代码,但还未完善:
Object.defineProperty(Document.prototype, "addEventListener", { value: function () { console.log("addEventListener of type ...? was fired"); // execute original function } });
要求实现点击文档时输出:
addEventListener of type click was fired
click event fired
或按下按键时输出:
addEventListener of type keypress was fired
keypress event fired
补充说明:调试器无法满足需求,需要知晓网站存在哪些事件监听器,并实现对大量网站的自动化检测。
解决方案
你需要先保存原始的addEventListener方法,再在重写的函数中调用它,同时捕获事件类型参数。完整代码如下:
// 保存原始的addEventListener方法 const originalAddEventListener = Document.prototype.addEventListener; // 重写addEventListener Object.defineProperty(Document.prototype, "addEventListener", { value: function(type, listener, options) { // 打印监听的事件类型 console.log(`addEventListener of type ${type} was fired`); // 调用原始方法,保留原有逻辑 originalAddEventListener.call(this, type, listener, options); } });
关键说明
- 保存原始方法:先将
Document.prototype上的原生addEventListener存入变量,避免重写后丢失原有功能。 - 捕获事件类型:自定义函数的第一个参数
type就是监听的事件类型(如click、keypress),直接通过模板字符串输出即可。 - 执行原逻辑:使用
call方法调用原始函数,确保this指向当前document对象,同时传递所有参数(包括可选的options),保证原有事件监听逻辑正常运行。
在Firefox控制台执行这段代码后,点击页面或按下按键,就能得到符合要求的日志输出,同时也能自动记录所有后续添加的事件监听器类型,满足批量网站检测的需求。
内容的提问来源于stack exchange,提问作者Tim MG
相关产品推荐
相关产品推荐

