javascript - 带有包装监听器的 AddEventListener
问题描述
每当触发点击事件时,我都会尝试运行自定义代码。这是我到目前为止所拥有的:
const origHandler = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (eventName, eventHandler, options) {
let handler = eventHandler;
const target = this;
origHandler.call(this, eventName, function (e) {
// Do something with e
doSomething(e);
// Run original function
handler.call(target, e);
}, options);
};
我也在使用这个多选下拉插件。使用上面的代码,单击下拉元素不会做任何事情,直到我单击它几次。如果我只执行以下操作,它就可以正常工作:
origHandler.call(this, eventName, handler, options);
但是,上述内容不允许我在调用处理程序时运行自定义代码。我能做些什么来创建一个也适用于这些类型插件的包装器吗?
此问题并非特定于此插件,因为我已经看到应用程序中的其他一些插件也因此代码而中断。
解决方案
不完整的算法
发布的代码调用(原始)addEventListener
带有匿名函数参数。这意味着任何作为其函数参数removeEventListener
提供的调用代码都将失败 - 它永远不会与匿名函数匹配。handler
要成功添加一个钩子addEventListener
,需要实现一个互补的钩子removeEventListener
和额外的逻辑,以实现正确删除添加的侦听器。
这并不意味着遇到的特定问题是专门由打补丁引起的addEventListener
,但这样做肯定会产生代码故障。
一般来说prototype
,如果可能的话,最好避免修补全局函数的对象属性。
替代使用捕获
在包含任何库脚本之前,添加一个使用事件捕获的文档点击事件侦听器,应该允许在被其他任何东西处理之前检查每个点击事件:
document.addEventListener("click", function(e){
// do something with event
console.log("click event type: %s on %s", e.type, e.target.tagName);
}, {capture:true});
body {background-color: white}
html {background-color: grey}
Click me!
推荐阅读
- java - Java Spring - 如何接受 RequestParam,并从 url 中删除?
- google-sheets - 搜索一个 Google 表格以将一行数据添加到另一个
- ruby-on-rails - 部署到 gcloud 时找不到捆绑包
- java - 如何使用archunit验证方法注释是否使用具有特定值的属性
- vim - 替换状态行标志中的文本
- php - 删除了 .php 扩展名,但现在它说页面不存在
- sql - 如何在 postgresql 中转换为十进制?
- recaptcha - 在 GUI 中显示来自 html-unit 的 reCaptcha
- php - 单个 WP_Query 可以从 X 标签获取帖子,但如果没有结果,则回退到 X 类别
- c++ - 什么时候可以安全地释放我传递给 DirectX 的内存?