I have installed two separate userscripts, each requiring to invoke some code with document.body.onkeydown
. However, I've noticed that with both userscripts enabled, only the latter event handler gets called.
Apparently, both userscripts are sharing the same DOM. This is contrary to my experience with Chrome extensions, where each Chrome extension has its own sandbox.
Either way, now how do I to fix this problem? I want both handlers to fire, and remain separate from each other.
I am executing my userscripts inside an IIFE with use strict mode enabled.
Using document.body.keydown
will set the callback to the keydown
event. Setting it again will replace the old one. Hence the latter script's event callback gets fired.
Instead use, document.body.addEventListener(<callback>)
in both so, both the events will present.
In the below example, first keydown will get overridden by the second one. The addEventListener will append an listener to the keydown
event. So on pressing a
only 3rd event fired. On pressing b
, both 2nd and 3rd are fired.
This is because the events added via the older method is added as like attribute values. Like,
<button id="show" onclick="show()">Click</button>
Hence, it got replaced.
The addEventListener
adds the listener to the list of EventListners of the DOM Object.
In the example I replaced the onclick
attribute with the function hide
via the older method, hence it calls only the hide
method.
For more info, please refer MDN Docs
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>