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 mon 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?
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 mon 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?
-
1
Can't answer your exact question, but note that you have an infinite loop by dispatching this event from
document
without any checks:{target} -> document
, dispatch:#query -> document
, dispatch:#query -> document
, etc. "The event is subject to the same capturing and bubbling behavior as directly dispatched events." – Jonathan Lonowski Commented May 14, 2012 at 16:37 - Right, I'd need to cancel the document-level event after dispatching it. – Channel72 Commented May 14, 2012 at 16:38
- Does this answer your question? Clone a DOM event object to re-dispatch – mfluehr Commented Dec 4, 2020 at 21:46
3 Answers
Reset to default 3Here'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 plex and intricate but it works ;)
For further infos:
- Create Event
- Event initKeyEvent
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.
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.