首页 > 解决方案 > 如何防止附加在一个用户脚本中的事件处理程序干扰另一个?

问题描述

我已经安装了两个单独的用户脚本,每个都需要使用document.body.onkeydown. 但是,我注意到启用两个用户脚本后,只有后一个事件处理程序被调用。

显然,两个用户脚本共享同一个 DOM。这与我使用 Chrome 扩展程序的经验相反,每个 Chrome 扩展程序都有自己的沙箱。

无论哪种方式,现在我该如何解决这个问题?我希望两个处理程序都开火,并彼此分开。

我在启用了使用严格模式的 IIFE 中执行我的用户脚本。

标签: javascriptuserscripts

解决方案


使用document.body.keydown会将回调设置为keydown事件。再次设置它将替换旧的。因此后一个脚本的事件回调被触发。

相反,document.body.addEventListener(<callback>)在这两种情况下,这两个事件都会出现。

在下面的示例中,第一个 keydown 将被第二个覆盖。addEventListener 将向keydown事件附加一个侦听器。因此,按下a仅触发第 3 个事件。按下b时,第 2 和第 3 都被触发。

这是因为通过旧方法添加的事件被添加为属性值。像,

<button id="show" onclick="show()">Click</button> 因此,它被替换了。

addEventListener侦听器添加到 DOM 对象的 EventListner 列表中。

在示例中,我通过旧方法将onclick属性替换为函数,因此它仅调用方法。hidehide

有关更多信息,请参阅MDN 文档

document.body.onkeydown = function(event){if(event.key=="a")console.log("keydown")};
document.body.onkeydown = function(event){if(event.key=="b")console.log("b keydown")};

document.body.addEventListener("keydown",function(){console.log("addEventListener")})

function show(){console.log("show")}
function hide(){console.log("hide")}

var element = document.getElementById("show");
element.onclick=hide;
<button id="show" onclick="show()">Click</button>


推荐阅读