Reputation: 24719
Is there a simple way to "forward" an event in Javascript? My ultimate objective here is to enhance UI responsiveness in the following manner: I have a website with a single input text field that submits a query to a backend database. If the user presses a key when the input field is not in focus, I'd like to capture the keypress event at the document level, and forward it to the input field. (This seems like a fairly common way to enhance UI responsiveness, for example, Google does this with their main search site.)
So I have a text input field like this:
<input id="query" onkeydown="f(event)">
And I attempt to forward the event like this:
function handler(ev)
{
var query = document.getElementById("query");
query.dispatchEvent(ev);
}
document.addEventListener("keydown", handler, false);
Now, ignoring the cross-browser issues with addEventListener
and dispatchEvent
, this doesn't even work on Firefox which supports both of those functions. The Javascript interpreter throws an exception: Error: uncaught exception: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMEventTarget.dispatchEvent]"
So, is it even possible to forward events like this? Or do I need to create a new event using initKeyEvent
and then dispatch that event to the input element?
Upvotes: 8
Views: 8178
Reputation: 2422
Following up on @Bergi's answer, the solution that works for me is to simply redirect the focus
- that way the event will go where you want it to! For instance:
document.addEventListener('keydown', function(evt) {
document.getElementById('query').focus();
}, false);
This redirects all keydown events to the query
element.
Upvotes: 1
Reputation: 8113
Here's an example of keyboard events:
HTML file (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Stackoverflow</title>
<script type="text/javascript" src="sof.js"> </script>
</head>
<body>
<input id="query" onkeydown="f(event);"/>
</body>
</html>
Javascript file (sof.js):
function simulateKeyDown () {
// DOM Level 3 events
var evt = document.createEvent ("KeyboardEvent");
// DOM Level 3 events
evt.initKeyboardEvent ("keydown", false, false, null, false, false, false, false, 0, 0);
var query = document.getElementById ('query');
query.dispatchEvent (evt);
}
window.onload = function () {
document.addEventListener ('keydown', simulateKeyDown, false);
}
function f (ev) {
console.log ('ciao');
}
As you can see, when the window is loaded it attaches a new handler to the keydown event of the document. When a key is pressed, a new KeyboardEvent event is created, intialized (with 'keydown') and then dispatched to the input element. Yes, it's a little complex and intricate but it works ;)
For further infos:
Upvotes: 3
Reputation: 664434
I'm not sure about forwarding, but I think you can't. Yet, my solution to the initial problem is
document.addEventListener("keydown", function(e) {
if (e.target.oMatchesSelector("form *, fieldset *, input, textarea"))
return; // Opera-specific, but I think you get the point of MatchesSelector
if (e.metaKey || e.ctrlKey)
return;
if (e.keyCode < 46 || e.keyCode > 90)
return;
document.getElementById("query").focus();
}, false);
The keydown event is not repsonsible for the chararcter input, so focusing the input will be enough onkeydown - the character will appear onkeyup.
Upvotes: 1