Related
Is it possible to simulate key press events programmatically in JavaScript?
A non-jquery version that works in both webkit and gecko:
var keyboardEvent = document.createEvent('KeyboardEvent');
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent';
keyboardEvent[initMethod](
'keydown', // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
40, // keyCode: unsigned long - the virtual key code, else 0
0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
You can dispatch keyboard events on an EventTarget (element, Window, Document, others) like this:
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
However, dispatchEvent might not update the input field value, and it might not trigger behavior that a regular keyboard press does, likely because of the Event.isTrusted property, which I don't know if there's a way to get around
But you can also change an input by setting its value.
element.value += "a";
Example:
let element = document.querySelector('input');
element.onkeydown = e => alert(e.key);
changeValButton.onclick = () => element.value += "a";
dispatchButton.onclick = () => {
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
}
<input/>
<button id="dispatchButton">Press to dispatch event </button>
<button id="changeValButton">Press to change value </button>
You can add more properties to the event as needed, as in this answer. Take a look at the KeyboardEvent documentation
element.dispatchEvent(new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
}));
Also, since keypress is deprecated you can use keydown + keyup, for example:
element.dispatchEvent(new KeyboardEvent('keydown', {'key':'Shift'} ));
element.dispatchEvent(new KeyboardEvent( 'keyup' , {'key':'Shift'} ));
For pages with ReactJS, this is a thread for trying to simulate keyboard behavior
If you are ok to use jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({
type: 'keypress',
which: character.charCodeAt(0)
});
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>
What you can do is programmatically trigger keyevent listeners by firing keyevents. It makes sense to allow this from a sandboxed security-perspective. Using this ability, you can then apply a typical observer-pattern. You could call this method "simulating".
Below is an example of how to accomplish this in the W3C DOM standard along with jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
This example is adapted from: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
In jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
But as of recently, there is no [DOM] way to actually trigger keyevents leaving the browser-sandbox. And all major browser vendors will adhere to that security concept.
As for plugins such as Adobe Flash - which are based on the NPAPI-, and permit bypassing the sandbox: these are phasing-out ; Firefox.
Detailed Explanation:
You cannot and you must not for security reasons (as Pekka already pointed out). You will always require a user interaction in between. Additionally imagine the chance of the browser vendors getting sued by users, as various programmatic keyboard events will have led to spoofing attacks.
See this post for alternatives and more details. There is always the flash based copy-and-paste. Here is an elegant example. At the same time it is a testimony why the web is moving away from plugin vendors.
There is a similar security mindset applied in case of the opt-in CORS policy to access remote content programmatically.
The answer is:
There is no way to programmatically trigger input keys in the sandboxed browser environment under normal circumstances.
Bottomline: I am not saying it will not be possible in the future, under special browser-modes and/or privileges towards the end-goal of gaming, or similar user-experiences. However prior to entering such modes, the user will be asked for permissions and risks, similar to the Fullscreen API model.
Useful: In the context of KeyCodes, this tool and keycode mapping will come in handy.
Disclosure: The answer is based on the answer here.
As of 2019, this solution has worked for me:
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
})
);
I used this in my browser game, in order to support mobile devices with a simulated keypad.
Clarification: This code dispatches a single keydown event, while a real key press would trigger one keydown event (or several of them if it is held longer), and then one keyup event when you release that key. If you need keyup events too, it is also possible to simulate keyup events by changing "keydown" to "keyup" in the code snippet.
This also sends the event to the entire webpage, hence the document. If you want only a specific element to receive the event, you can substitute document for the desired element.
You can use dispatchEvent():
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
I didn't test this, but it's adapted from the code on dispatchEvent()'s documentation. You'll probably want to read through that, and also the docs for createEvent() and initKeyEvent().
You can create and dispatch keyboard events, and they will trigger appropriate registered event handlers, however they will not produce any text, if dispatched to input element for example.
To fully simulate text input you need to produce a sequence of keyboard events plus explicitly set the text of input element. The sequence of events depends on how thoroughly you want to simulate text input.
The simplest form would be:
$('input').val('123');
$('input').change();
In some cases keypress event can't provide required funtionality. From mozilla docs we can see that the feature is deprecated:
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
So, since the keypress event is combined from the two consequently fired events keydown, and the following it keyup for the same key, just generate the events one-by-one:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
For those interested, you can, in-fact recreate keyboard input events reliably. In order to change text in input area (move cursors, or the page via an input character) you have to follow the DOM event model closely: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
The model should do:
focus (dispatched on the DOM with the target set)
Then for each character:
keydown (dispatched on the DOM)
beforeinput (dispatched at the target if its a textarea or input)
keypress (dispatched on the DOM)
input (dispatched at the target if its a textarea or input)
change (dispatched at the target if its a select)
keyup (dispatched on the DOM)
Then, optionally for most:
blur (dispatched on the DOM with the target set)
This actually changes the text in the page via javascript (without modifying value statements) and sets off any javascript listeners/handlers appropriately. If you mess up the sequence javascript will not fire in the appropriate order, the text in the input box will not change, the selections will not change or the cursor will not move to the next space in the text area.
Unfortunately the code was written for an employer under an NDA so I cannot share it, but it is definitely possible but you must recreate the entire key input "stack" for each element in the correct order.
Edit: I'm not the original poster of this answer, but I have tested it and I can't get it to work for updating an input field. Here's a code snippet with the code for others to try or review
let element = document.querySelector('input');
element.onkeydown = e => console.log('keydown on element: ' + e.key);
document.onkeydown = e => console.log('keydown on document: ' + e.key + " " + e.target);
dispatchButton.onclick = () => dispatchKey(element, 'a')
dispatchKey = (target, key) => {
let dom = document;
// focus (dispatched on the DOM with the target set)
let ev = new Event('focus', {target: target});
// this part seems to not work? when logging the
// target in the onkeypress function it shows `document` instead of `input`
// I also tried these and got the same behavior
// ev.target = target;
// and
// Object.defineProperty(ev, 'target', {writable: false, value: target});
dom.dispatchEvent(ev);
// keydown (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keydown', {'key': key, target: target}));
// beforeinput (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('beforeinput'));
// keypress (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keypress', {'key': key}));
// input (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('input'));
// change (dispatched at the target if it's a select)
// keyup (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keyup', {'key': key}));
// Then, optionally for most:
// blur (dispatched on the DOM with the target set)
dom.dispatchEvent(new Event('blur', {target: target}));
console.log('dispatched');
}
<input/>
<button id="dispatchButton">Press to dispatch events </button>
Building on the answer from alex2k8, here's a revised version that works in all browsers that jQuery supports (the problem was in missing arguments to jQuery.event.trigger, which is easy to forget when using that internal function).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
You could even push this further and let it not only simulate the event but actually insert the character (if it is an input element), however there are many cross-browser gotcha's when trying to do that. Better use a more elaborate plugin like SendKeys.
just use CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex want to simulate ctrl+z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
This approach support cross-browser changing the value of key code.
Source
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
I wanted to simulate a 'Tab' press... Expanding on Trevor's answer, we can see that a special key like 'tab' does get pressed but we don't see the actual result which a 'tab' press would have...
tried with dispatching these events for 'activeElement' as well as the global document object both - code for both added below;
snippet below:
var element = document.getElementById("firstInput");
document.addEventListener("keydown", function(event) {
console.log('we got key:', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
/* enter is pressed */
if (event.keyCode == 13) {
console.log('enter pressed:', event);
theKey = 'Tab';
attributes = {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
};
setTimeout(function() {
/* event.keyCode = 13; event.target.value += 'b'; */
var e = new window.KeyboardEvent('focus', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.activeElement.dispatchEvent(e);
}, 4);
setTimeout(function() {
var e = new window.KeyboardEvent('focus', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.dispatchEvent(e);
}, 100);
} else if (event.keyCode != 0) {
console.log('we got a non-enter press...: :', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
}
});
<h2>convert each enter to a tab in JavaScript... check console for output</h2>
<h3>we dispatchEvents on the activeElement... and the global element as well</h3>
<input type='text' id='firstInput' />
<input type='text' id='secondInput' />
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()">
Click me to display Date and Time.</button>
<p id="demo"></p>
The critical part of getting this to work is to realize that charCode, keyCode and which are all deprecated methods. Therefore if the code processing the key press event uses any of these three, then it'll receive a bogus answer (e.g. a default of 0).
As long as you access the key press event with a non-deprecated method, such as key, you should be OK.
For completion, I've added the basic Javascript code for triggering the event:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
This worked for me and it does simulate a keyup for my textaera. if you want it for the entire page just put the KeySimulation() on <body> like this <body onmousemove="KeySimulation()"> or if not onmousemove then onmouseover or onload works too.
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Here's a library that really helps: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
I don't know from where did it came from, but it is helpful. It adds a .simulate() method to window.KeyEvent, so you use it simply with KeyEvent.simulate(0, 13) for simulating an enter or KeyEvent.simulate(81, 81) for a 'Q'.
I got it at https://github.com/ccampbell/mousetrap/tree/master/tests.
It was single rowed once due to easy usage in a console context. But probably useful still.
var pressthiskey = "q"/* <-- q for example */;
var e = new Event("keydown");
e.key = pressthiskey;
e.keyCode = e.key.charCodeAt(0);
e.which = e.keyCode;
e.altKey = false;
e.ctrlKey = true;
e.shiftKey = false;
e.metaKey = false;
e.bubbles = true;
document.dispatchEvent(e);
you can simulate input password with this code:
tested on chrome 100% work
DoCustomEvent('password', '#loginpin');
function DoCustomEvent(ct, elem){
var key;
var pressEvent = document.createEvent("CustomEvent");
pressEvent.initCustomEvent("keypress", true, false);
for (var i =0; i < ct.length; ++i)
{
key = ct.charCodeAt(i);
pressEvent.bubbles = true;
pressEvent.cancelBubble = false;
pressEvent.returnValue = true;
pressEvent.key = ct.charAt(i);
pressEvent.keyCode = key;
pressEvent.which = key;
pressEvent.charCode = key;
pressEvent.shiftKey = false;
pressEvent.ctrlKey = false;
pressEvent.metaKey = false;
document.querySelector(elem).focus();
//keypress //beforeinput //input //sendkeys //select
setTimeout(function() {
var e = new window.KeyboardEvent('keypress', pressEvent);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', pressEvent);
document.activeElement.dispatchEvent(e);
}, 0);
document.querySelector(elem).value = document.querySelector(elem).value + ct.charAt(i);
}
Here is a solution that works in Chrome and Chromium (have only tested these platforms). It seems Chrome has some bug or own approach to handling key codes so this property has to be added separately to the KeyboardEvent.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
simulateKeydown(39, false, false, false);
Native JavaScript with TypeScript supported solution:
Type the keyCode or whichever property you are using and cast it to KeyboardEventInit
Example
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
That's what I tried with js/typescript in chrome. Thanks to
this answer for inspiration.
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
{
// example
document.querySelector('input').addEventListener("keypress", e => console.log("keypress", e.key))
// unfortunatelly doesn't trigger submit
document.querySelector('form').addEventListener("submit", e => {
e.preventDefault();
console.log("submit")
})
}
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
<form>
<input>
</form>
I know the question asks for a javascript way of simulating a keypress. But for those who are looking for a jQuery way of doing things:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Building on #aljgom's answer:
This worked great for me. Instead of dispatching the event to an element like aljgom had suggested, just dispatch it to the document.
document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));
as soon as the user presses the key in question you can store a reference to that even and use it on any HTML other element:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
you can set the keyCode if you create your own event, you can copy existing parameters from any real keyboard event (ignoring targets since its the job of dispatchEvent) and :
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
This is what I managed to find:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
Best way to js full screen toggle method:
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else if (document.exitFullscreen) {
document.exitFullscreen();
}
}
Is it possible to simulate key press events programmatically in JavaScript?
A non-jquery version that works in both webkit and gecko:
var keyboardEvent = document.createEvent('KeyboardEvent');
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent';
keyboardEvent[initMethod](
'keydown', // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
40, // keyCode: unsigned long - the virtual key code, else 0
0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
You can dispatch keyboard events on an EventTarget (element, Window, Document, others) like this:
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
However, dispatchEvent might not update the input field value, and it might not trigger behavior that a regular keyboard press does, likely because of the Event.isTrusted property, which I don't know if there's a way to get around
But you can also change an input by setting its value.
element.value += "a";
Example:
let element = document.querySelector('input');
element.onkeydown = e => alert(e.key);
changeValButton.onclick = () => element.value += "a";
dispatchButton.onclick = () => {
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
}
<input/>
<button id="dispatchButton">Press to dispatch event </button>
<button id="changeValButton">Press to change value </button>
You can add more properties to the event as needed, as in this answer. Take a look at the KeyboardEvent documentation
element.dispatchEvent(new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
}));
Also, since keypress is deprecated you can use keydown + keyup, for example:
element.dispatchEvent(new KeyboardEvent('keydown', {'key':'Shift'} ));
element.dispatchEvent(new KeyboardEvent( 'keyup' , {'key':'Shift'} ));
For pages with ReactJS, this is a thread for trying to simulate keyboard behavior
If you are ok to use jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({
type: 'keypress',
which: character.charCodeAt(0)
});
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>
What you can do is programmatically trigger keyevent listeners by firing keyevents. It makes sense to allow this from a sandboxed security-perspective. Using this ability, you can then apply a typical observer-pattern. You could call this method "simulating".
Below is an example of how to accomplish this in the W3C DOM standard along with jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
This example is adapted from: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
In jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
But as of recently, there is no [DOM] way to actually trigger keyevents leaving the browser-sandbox. And all major browser vendors will adhere to that security concept.
As for plugins such as Adobe Flash - which are based on the NPAPI-, and permit bypassing the sandbox: these are phasing-out ; Firefox.
Detailed Explanation:
You cannot and you must not for security reasons (as Pekka already pointed out). You will always require a user interaction in between. Additionally imagine the chance of the browser vendors getting sued by users, as various programmatic keyboard events will have led to spoofing attacks.
See this post for alternatives and more details. There is always the flash based copy-and-paste. Here is an elegant example. At the same time it is a testimony why the web is moving away from plugin vendors.
There is a similar security mindset applied in case of the opt-in CORS policy to access remote content programmatically.
The answer is:
There is no way to programmatically trigger input keys in the sandboxed browser environment under normal circumstances.
Bottomline: I am not saying it will not be possible in the future, under special browser-modes and/or privileges towards the end-goal of gaming, or similar user-experiences. However prior to entering such modes, the user will be asked for permissions and risks, similar to the Fullscreen API model.
Useful: In the context of KeyCodes, this tool and keycode mapping will come in handy.
Disclosure: The answer is based on the answer here.
As of 2019, this solution has worked for me:
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
})
);
I used this in my browser game, in order to support mobile devices with a simulated keypad.
Clarification: This code dispatches a single keydown event, while a real key press would trigger one keydown event (or several of them if it is held longer), and then one keyup event when you release that key. If you need keyup events too, it is also possible to simulate keyup events by changing "keydown" to "keyup" in the code snippet.
This also sends the event to the entire webpage, hence the document. If you want only a specific element to receive the event, you can substitute document for the desired element.
You can use dispatchEvent():
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
I didn't test this, but it's adapted from the code on dispatchEvent()'s documentation. You'll probably want to read through that, and also the docs for createEvent() and initKeyEvent().
You can create and dispatch keyboard events, and they will trigger appropriate registered event handlers, however they will not produce any text, if dispatched to input element for example.
To fully simulate text input you need to produce a sequence of keyboard events plus explicitly set the text of input element. The sequence of events depends on how thoroughly you want to simulate text input.
The simplest form would be:
$('input').val('123');
$('input').change();
In some cases keypress event can't provide required funtionality. From mozilla docs we can see that the feature is deprecated:
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
So, since the keypress event is combined from the two consequently fired events keydown, and the following it keyup for the same key, just generate the events one-by-one:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
For those interested, you can, in-fact recreate keyboard input events reliably. In order to change text in input area (move cursors, or the page via an input character) you have to follow the DOM event model closely: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
The model should do:
focus (dispatched on the DOM with the target set)
Then for each character:
keydown (dispatched on the DOM)
beforeinput (dispatched at the target if its a textarea or input)
keypress (dispatched on the DOM)
input (dispatched at the target if its a textarea or input)
change (dispatched at the target if its a select)
keyup (dispatched on the DOM)
Then, optionally for most:
blur (dispatched on the DOM with the target set)
This actually changes the text in the page via javascript (without modifying value statements) and sets off any javascript listeners/handlers appropriately. If you mess up the sequence javascript will not fire in the appropriate order, the text in the input box will not change, the selections will not change or the cursor will not move to the next space in the text area.
Unfortunately the code was written for an employer under an NDA so I cannot share it, but it is definitely possible but you must recreate the entire key input "stack" for each element in the correct order.
Edit: I'm not the original poster of this answer, but I have tested it and I can't get it to work for updating an input field. Here's a code snippet with the code for others to try or review
let element = document.querySelector('input');
element.onkeydown = e => console.log('keydown on element: ' + e.key);
document.onkeydown = e => console.log('keydown on document: ' + e.key + " " + e.target);
dispatchButton.onclick = () => dispatchKey(element, 'a')
dispatchKey = (target, key) => {
let dom = document;
// focus (dispatched on the DOM with the target set)
let ev = new Event('focus', {target: target});
// this part seems to not work? when logging the
// target in the onkeypress function it shows `document` instead of `input`
// I also tried these and got the same behavior
// ev.target = target;
// and
// Object.defineProperty(ev, 'target', {writable: false, value: target});
dom.dispatchEvent(ev);
// keydown (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keydown', {'key': key, target: target}));
// beforeinput (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('beforeinput'));
// keypress (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keypress', {'key': key}));
// input (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('input'));
// change (dispatched at the target if it's a select)
// keyup (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keyup', {'key': key}));
// Then, optionally for most:
// blur (dispatched on the DOM with the target set)
dom.dispatchEvent(new Event('blur', {target: target}));
console.log('dispatched');
}
<input/>
<button id="dispatchButton">Press to dispatch events </button>
Building on the answer from alex2k8, here's a revised version that works in all browsers that jQuery supports (the problem was in missing arguments to jQuery.event.trigger, which is easy to forget when using that internal function).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
You could even push this further and let it not only simulate the event but actually insert the character (if it is an input element), however there are many cross-browser gotcha's when trying to do that. Better use a more elaborate plugin like SendKeys.
just use CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex want to simulate ctrl+z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
This approach support cross-browser changing the value of key code.
Source
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
I wanted to simulate a 'Tab' press... Expanding on Trevor's answer, we can see that a special key like 'tab' does get pressed but we don't see the actual result which a 'tab' press would have...
tried with dispatching these events for 'activeElement' as well as the global document object both - code for both added below;
snippet below:
var element = document.getElementById("firstInput");
document.addEventListener("keydown", function(event) {
console.log('we got key:', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
/* enter is pressed */
if (event.keyCode == 13) {
console.log('enter pressed:', event);
theKey = 'Tab';
attributes = {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
};
setTimeout(function() {
/* event.keyCode = 13; event.target.value += 'b'; */
var e = new window.KeyboardEvent('focus', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.activeElement.dispatchEvent(e);
}, 4);
setTimeout(function() {
var e = new window.KeyboardEvent('focus', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.dispatchEvent(e);
}, 100);
} else if (event.keyCode != 0) {
console.log('we got a non-enter press...: :', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
}
});
<h2>convert each enter to a tab in JavaScript... check console for output</h2>
<h3>we dispatchEvents on the activeElement... and the global element as well</h3>
<input type='text' id='firstInput' />
<input type='text' id='secondInput' />
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()">
Click me to display Date and Time.</button>
<p id="demo"></p>
The critical part of getting this to work is to realize that charCode, keyCode and which are all deprecated methods. Therefore if the code processing the key press event uses any of these three, then it'll receive a bogus answer (e.g. a default of 0).
As long as you access the key press event with a non-deprecated method, such as key, you should be OK.
For completion, I've added the basic Javascript code for triggering the event:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
This worked for me and it does simulate a keyup for my textaera. if you want it for the entire page just put the KeySimulation() on <body> like this <body onmousemove="KeySimulation()"> or if not onmousemove then onmouseover or onload works too.
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Here's a library that really helps: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
I don't know from where did it came from, but it is helpful. It adds a .simulate() method to window.KeyEvent, so you use it simply with KeyEvent.simulate(0, 13) for simulating an enter or KeyEvent.simulate(81, 81) for a 'Q'.
I got it at https://github.com/ccampbell/mousetrap/tree/master/tests.
It was single rowed once due to easy usage in a console context. But probably useful still.
var pressthiskey = "q"/* <-- q for example */;
var e = new Event("keydown");
e.key = pressthiskey;
e.keyCode = e.key.charCodeAt(0);
e.which = e.keyCode;
e.altKey = false;
e.ctrlKey = true;
e.shiftKey = false;
e.metaKey = false;
e.bubbles = true;
document.dispatchEvent(e);
you can simulate input password with this code:
tested on chrome 100% work
DoCustomEvent('password', '#loginpin');
function DoCustomEvent(ct, elem){
var key;
var pressEvent = document.createEvent("CustomEvent");
pressEvent.initCustomEvent("keypress", true, false);
for (var i =0; i < ct.length; ++i)
{
key = ct.charCodeAt(i);
pressEvent.bubbles = true;
pressEvent.cancelBubble = false;
pressEvent.returnValue = true;
pressEvent.key = ct.charAt(i);
pressEvent.keyCode = key;
pressEvent.which = key;
pressEvent.charCode = key;
pressEvent.shiftKey = false;
pressEvent.ctrlKey = false;
pressEvent.metaKey = false;
document.querySelector(elem).focus();
//keypress //beforeinput //input //sendkeys //select
setTimeout(function() {
var e = new window.KeyboardEvent('keypress', pressEvent);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', pressEvent);
document.activeElement.dispatchEvent(e);
}, 0);
document.querySelector(elem).value = document.querySelector(elem).value + ct.charAt(i);
}
Here is a solution that works in Chrome and Chromium (have only tested these platforms). It seems Chrome has some bug or own approach to handling key codes so this property has to be added separately to the KeyboardEvent.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
simulateKeydown(39, false, false, false);
Native JavaScript with TypeScript supported solution:
Type the keyCode or whichever property you are using and cast it to KeyboardEventInit
Example
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
That's what I tried with js/typescript in chrome. Thanks to
this answer for inspiration.
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
{
// example
document.querySelector('input').addEventListener("keypress", e => console.log("keypress", e.key))
// unfortunatelly doesn't trigger submit
document.querySelector('form').addEventListener("submit", e => {
e.preventDefault();
console.log("submit")
})
}
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
<form>
<input>
</form>
I know the question asks for a javascript way of simulating a keypress. But for those who are looking for a jQuery way of doing things:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Building on #aljgom's answer:
This worked great for me. Instead of dispatching the event to an element like aljgom had suggested, just dispatch it to the document.
document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));
as soon as the user presses the key in question you can store a reference to that even and use it on any HTML other element:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
you can set the keyCode if you create your own event, you can copy existing parameters from any real keyboard event (ignoring targets since its the job of dispatchEvent) and :
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
This is what I managed to find:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
Best way to js full screen toggle method:
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else if (document.exitFullscreen) {
document.exitFullscreen();
}
}
What is the best way to simulate a user entering text in a text input box in JS and/or jQuery?
I don't want to actually put text in the input box, I just want to trigger all the event handlers that would normally get triggered by a user typing info into a input box. This means focus, keydown, keypress, keyup, and blur. I think.
So how would one accomplish this?
You can trigger any of the events with a direct call to them, like this:
$(function() {
$('item').keydown();
$('item').keypress();
$('item').keyup();
$('item').blur();
});
Does that do what you're trying to do?
You should probably also trigger .focus() and potentially .change()
If you want to trigger the key-events with specific keys, you can do so like this:
$(function() {
var e = $.Event('keypress');
e.which = 65; // Character 'A'
$('item').trigger(e);
});
There is some interesting discussion of the keypress events here: jQuery Event Keypress: Which key was pressed?, specifically regarding cross-browser compatability with the .which property.
You could dispatching events like
el.dispatchEvent(new Event('focus'));
el.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
To trigger an enter keypress, I had to modify #ebynum response, specifically, using the keyCode property.
e = $.Event('keyup');
e.keyCode= 13; // enter
$('input').trigger(e);
Here's a vanilla js example to trigger any event:
function triggerEvent(el, type){
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
You can achieve this with: EventTarget.dispatchEvent(event) and by passing in a new KeyboardEvent as the event.
For example: element.dispatchEvent(new KeyboardEvent('keypress', {'key': 'a'}))
Working example:
// get the element in question
const input = document.getElementsByTagName("input")[0];
// focus on the input element
input.focus();
// add event listeners to the input element
input.addEventListener('keypress', (event) => {
console.log("You have pressed key: ", event.key);
});
input.addEventListener('keydown', (event) => {
console.log(`key: ${event.key} has been pressed down`);
});
input.addEventListener('keyup', (event) => {
console.log(`key: ${event.key} has been released`);
});
// dispatch keyboard events
input.dispatchEvent(new KeyboardEvent('keypress', {'key':'h'}));
input.dispatchEvent(new KeyboardEvent('keydown', {'key':'e'}));
input.dispatchEvent(new KeyboardEvent('keyup', {'key':'y'}));
<input type="text" placeholder="foo" />
MDN dispatchEvent
MDN KeyboardEvent
You're now able to do:
var e = $.Event("keydown", {keyCode: 64});
First of all, I need to say that sample from Sionnach733 worked flawlessly. Some users complain about absent of actual examples. Here is my two cents. I've been working on mouse click simulation when using this site: https://www.youtube.com/tv. You can open any video and try run this code. It performs switch to next video.
function triggerEvent(el, type, keyCode) {
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.keyCode = keyCode;
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.keyCode = keyCode;
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
var nextButton = document.getElementsByClassName('icon-player-next')[0];
triggerEvent(nextButton, 'keyup', 13); // simulate mouse/enter key press
For typescript cast to KeyboardEventInit and provide the correct keyCode integer
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
I thought I would draw your attention that in the specific context where a listener was defined within a jQuery plugin, then the only thing that successfully simulated the keypress event for me, eventually caught by that listener, was to use setTimeout().
e.g.
setTimeout(function() { $("#txtName").keypress() } , 1000);
Any use of $("#txtName").keypress() was ignored, although placed at the end of the .ready() function. No particular DOM supplement was being created asynchronously anyway.
Is it possible to simulate key press events programmatically in JavaScript?
A non-jquery version that works in both webkit and gecko:
var keyboardEvent = document.createEvent('KeyboardEvent');
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent';
keyboardEvent[initMethod](
'keydown', // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
40, // keyCode: unsigned long - the virtual key code, else 0
0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
You can dispatch keyboard events on an EventTarget (element, Window, Document, others) like this:
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
However, dispatchEvent might not update the input field value, and it might not trigger behavior that a regular keyboard press does, likely because of the Event.isTrusted property, which I don't know if there's a way to get around
But you can also change an input by setting its value.
element.value += "a";
Example:
let element = document.querySelector('input');
element.onkeydown = e => alert(e.key);
changeValButton.onclick = () => element.value += "a";
dispatchButton.onclick = () => {
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
}
<input/>
<button id="dispatchButton">Press to dispatch event </button>
<button id="changeValButton">Press to change value </button>
You can add more properties to the event as needed, as in this answer. Take a look at the KeyboardEvent documentation
element.dispatchEvent(new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
}));
Also, since keypress is deprecated you can use keydown + keyup, for example:
element.dispatchEvent(new KeyboardEvent('keydown', {'key':'Shift'} ));
element.dispatchEvent(new KeyboardEvent( 'keyup' , {'key':'Shift'} ));
For pages with ReactJS, this is a thread for trying to simulate keyboard behavior
If you are ok to use jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({
type: 'keypress',
which: character.charCodeAt(0)
});
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>
What you can do is programmatically trigger keyevent listeners by firing keyevents. It makes sense to allow this from a sandboxed security-perspective. Using this ability, you can then apply a typical observer-pattern. You could call this method "simulating".
Below is an example of how to accomplish this in the W3C DOM standard along with jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
This example is adapted from: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
In jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
But as of recently, there is no [DOM] way to actually trigger keyevents leaving the browser-sandbox. And all major browser vendors will adhere to that security concept.
As for plugins such as Adobe Flash - which are based on the NPAPI-, and permit bypassing the sandbox: these are phasing-out ; Firefox.
Detailed Explanation:
You cannot and you must not for security reasons (as Pekka already pointed out). You will always require a user interaction in between. Additionally imagine the chance of the browser vendors getting sued by users, as various programmatic keyboard events will have led to spoofing attacks.
See this post for alternatives and more details. There is always the flash based copy-and-paste. Here is an elegant example. At the same time it is a testimony why the web is moving away from plugin vendors.
There is a similar security mindset applied in case of the opt-in CORS policy to access remote content programmatically.
The answer is:
There is no way to programmatically trigger input keys in the sandboxed browser environment under normal circumstances.
Bottomline: I am not saying it will not be possible in the future, under special browser-modes and/or privileges towards the end-goal of gaming, or similar user-experiences. However prior to entering such modes, the user will be asked for permissions and risks, similar to the Fullscreen API model.
Useful: In the context of KeyCodes, this tool and keycode mapping will come in handy.
Disclosure: The answer is based on the answer here.
As of 2019, this solution has worked for me:
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
})
);
I used this in my browser game, in order to support mobile devices with a simulated keypad.
Clarification: This code dispatches a single keydown event, while a real key press would trigger one keydown event (or several of them if it is held longer), and then one keyup event when you release that key. If you need keyup events too, it is also possible to simulate keyup events by changing "keydown" to "keyup" in the code snippet.
This also sends the event to the entire webpage, hence the document. If you want only a specific element to receive the event, you can substitute document for the desired element.
You can use dispatchEvent():
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
I didn't test this, but it's adapted from the code on dispatchEvent()'s documentation. You'll probably want to read through that, and also the docs for createEvent() and initKeyEvent().
You can create and dispatch keyboard events, and they will trigger appropriate registered event handlers, however they will not produce any text, if dispatched to input element for example.
To fully simulate text input you need to produce a sequence of keyboard events plus explicitly set the text of input element. The sequence of events depends on how thoroughly you want to simulate text input.
The simplest form would be:
$('input').val('123');
$('input').change();
In some cases keypress event can't provide required funtionality. From mozilla docs we can see that the feature is deprecated:
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
So, since the keypress event is combined from the two consequently fired events keydown, and the following it keyup for the same key, just generate the events one-by-one:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
For those interested, you can, in-fact recreate keyboard input events reliably. In order to change text in input area (move cursors, or the page via an input character) you have to follow the DOM event model closely: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
The model should do:
focus (dispatched on the DOM with the target set)
Then for each character:
keydown (dispatched on the DOM)
beforeinput (dispatched at the target if its a textarea or input)
keypress (dispatched on the DOM)
input (dispatched at the target if its a textarea or input)
change (dispatched at the target if its a select)
keyup (dispatched on the DOM)
Then, optionally for most:
blur (dispatched on the DOM with the target set)
This actually changes the text in the page via javascript (without modifying value statements) and sets off any javascript listeners/handlers appropriately. If you mess up the sequence javascript will not fire in the appropriate order, the text in the input box will not change, the selections will not change or the cursor will not move to the next space in the text area.
Unfortunately the code was written for an employer under an NDA so I cannot share it, but it is definitely possible but you must recreate the entire key input "stack" for each element in the correct order.
Edit: I'm not the original poster of this answer, but I have tested it and I can't get it to work for updating an input field. Here's a code snippet with the code for others to try or review
let element = document.querySelector('input');
element.onkeydown = e => console.log('keydown on element: ' + e.key);
document.onkeydown = e => console.log('keydown on document: ' + e.key + " " + e.target);
dispatchButton.onclick = () => dispatchKey(element, 'a')
dispatchKey = (target, key) => {
let dom = document;
// focus (dispatched on the DOM with the target set)
let ev = new Event('focus', {target: target});
// this part seems to not work? when logging the
// target in the onkeypress function it shows `document` instead of `input`
// I also tried these and got the same behavior
// ev.target = target;
// and
// Object.defineProperty(ev, 'target', {writable: false, value: target});
dom.dispatchEvent(ev);
// keydown (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keydown', {'key': key, target: target}));
// beforeinput (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('beforeinput'));
// keypress (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keypress', {'key': key}));
// input (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('input'));
// change (dispatched at the target if it's a select)
// keyup (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keyup', {'key': key}));
// Then, optionally for most:
// blur (dispatched on the DOM with the target set)
dom.dispatchEvent(new Event('blur', {target: target}));
console.log('dispatched');
}
<input/>
<button id="dispatchButton">Press to dispatch events </button>
Building on the answer from alex2k8, here's a revised version that works in all browsers that jQuery supports (the problem was in missing arguments to jQuery.event.trigger, which is easy to forget when using that internal function).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
You could even push this further and let it not only simulate the event but actually insert the character (if it is an input element), however there are many cross-browser gotcha's when trying to do that. Better use a more elaborate plugin like SendKeys.
just use CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex want to simulate ctrl+z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
This approach support cross-browser changing the value of key code.
Source
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
I wanted to simulate a 'Tab' press... Expanding on Trevor's answer, we can see that a special key like 'tab' does get pressed but we don't see the actual result which a 'tab' press would have...
tried with dispatching these events for 'activeElement' as well as the global document object both - code for both added below;
snippet below:
var element = document.getElementById("firstInput");
document.addEventListener("keydown", function(event) {
console.log('we got key:', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
/* enter is pressed */
if (event.keyCode == 13) {
console.log('enter pressed:', event);
theKey = 'Tab';
attributes = {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
};
setTimeout(function() {
/* event.keyCode = 13; event.target.value += 'b'; */
var e = new window.KeyboardEvent('focus', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.activeElement.dispatchEvent(e);
}, 4);
setTimeout(function() {
var e = new window.KeyboardEvent('focus', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.dispatchEvent(e);
}, 100);
} else if (event.keyCode != 0) {
console.log('we got a non-enter press...: :', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
}
});
<h2>convert each enter to a tab in JavaScript... check console for output</h2>
<h3>we dispatchEvents on the activeElement... and the global element as well</h3>
<input type='text' id='firstInput' />
<input type='text' id='secondInput' />
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()">
Click me to display Date and Time.</button>
<p id="demo"></p>
The critical part of getting this to work is to realize that charCode, keyCode and which are all deprecated methods. Therefore if the code processing the key press event uses any of these three, then it'll receive a bogus answer (e.g. a default of 0).
As long as you access the key press event with a non-deprecated method, such as key, you should be OK.
For completion, I've added the basic Javascript code for triggering the event:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
This worked for me and it does simulate a keyup for my textaera. if you want it for the entire page just put the KeySimulation() on <body> like this <body onmousemove="KeySimulation()"> or if not onmousemove then onmouseover or onload works too.
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Here's a library that really helps: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
I don't know from where did it came from, but it is helpful. It adds a .simulate() method to window.KeyEvent, so you use it simply with KeyEvent.simulate(0, 13) for simulating an enter or KeyEvent.simulate(81, 81) for a 'Q'.
I got it at https://github.com/ccampbell/mousetrap/tree/master/tests.
It was single rowed once due to easy usage in a console context. But probably useful still.
var pressthiskey = "q"/* <-- q for example */;
var e = new Event("keydown");
e.key = pressthiskey;
e.keyCode = e.key.charCodeAt(0);
e.which = e.keyCode;
e.altKey = false;
e.ctrlKey = true;
e.shiftKey = false;
e.metaKey = false;
e.bubbles = true;
document.dispatchEvent(e);
you can simulate input password with this code:
tested on chrome 100% work
DoCustomEvent('password', '#loginpin');
function DoCustomEvent(ct, elem){
var key;
var pressEvent = document.createEvent("CustomEvent");
pressEvent.initCustomEvent("keypress", true, false);
for (var i =0; i < ct.length; ++i)
{
key = ct.charCodeAt(i);
pressEvent.bubbles = true;
pressEvent.cancelBubble = false;
pressEvent.returnValue = true;
pressEvent.key = ct.charAt(i);
pressEvent.keyCode = key;
pressEvent.which = key;
pressEvent.charCode = key;
pressEvent.shiftKey = false;
pressEvent.ctrlKey = false;
pressEvent.metaKey = false;
document.querySelector(elem).focus();
//keypress //beforeinput //input //sendkeys //select
setTimeout(function() {
var e = new window.KeyboardEvent('keypress', pressEvent);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', pressEvent);
document.activeElement.dispatchEvent(e);
}, 0);
document.querySelector(elem).value = document.querySelector(elem).value + ct.charAt(i);
}
Here is a solution that works in Chrome and Chromium (have only tested these platforms). It seems Chrome has some bug or own approach to handling key codes so this property has to be added separately to the KeyboardEvent.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
simulateKeydown(39, false, false, false);
Native JavaScript with TypeScript supported solution:
Type the keyCode or whichever property you are using and cast it to KeyboardEventInit
Example
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
That's what I tried with js/typescript in chrome. Thanks to
this answer for inspiration.
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
{
// example
document.querySelector('input').addEventListener("keypress", e => console.log("keypress", e.key))
// unfortunatelly doesn't trigger submit
document.querySelector('form').addEventListener("submit", e => {
e.preventDefault();
console.log("submit")
})
}
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
<form>
<input>
</form>
I know the question asks for a javascript way of simulating a keypress. But for those who are looking for a jQuery way of doing things:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Building on #aljgom's answer:
This worked great for me. Instead of dispatching the event to an element like aljgom had suggested, just dispatch it to the document.
document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));
as soon as the user presses the key in question you can store a reference to that even and use it on any HTML other element:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
you can set the keyCode if you create your own event, you can copy existing parameters from any real keyboard event (ignoring targets since its the job of dispatchEvent) and :
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
This is what I managed to find:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
Best way to js full screen toggle method:
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else if (document.exitFullscreen) {
document.exitFullscreen();
}
}
Is it possible to simulate key press events programmatically in JavaScript?
A non-jquery version that works in both webkit and gecko:
var keyboardEvent = document.createEvent('KeyboardEvent');
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent';
keyboardEvent[initMethod](
'keydown', // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
40, // keyCode: unsigned long - the virtual key code, else 0
0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
You can dispatch keyboard events on an EventTarget (element, Window, Document, others) like this:
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
However, dispatchEvent might not update the input field value, and it might not trigger behavior that a regular keyboard press does, likely because of the Event.isTrusted property, which I don't know if there's a way to get around
But you can also change an input by setting its value.
element.value += "a";
Example:
let element = document.querySelector('input');
element.onkeydown = e => alert(e.key);
changeValButton.onclick = () => element.value += "a";
dispatchButton.onclick = () => {
element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));
}
<input/>
<button id="dispatchButton">Press to dispatch event </button>
<button id="changeValButton">Press to change value </button>
You can add more properties to the event as needed, as in this answer. Take a look at the KeyboardEvent documentation
element.dispatchEvent(new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
}));
Also, since keypress is deprecated you can use keydown + keyup, for example:
element.dispatchEvent(new KeyboardEvent('keydown', {'key':'Shift'} ));
element.dispatchEvent(new KeyboardEvent( 'keyup' , {'key':'Shift'} ));
For pages with ReactJS, this is a thread for trying to simulate keyboard behavior
If you are ok to use jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({
type: 'keypress',
which: character.charCodeAt(0)
});
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>
What you can do is programmatically trigger keyevent listeners by firing keyevents. It makes sense to allow this from a sandboxed security-perspective. Using this ability, you can then apply a typical observer-pattern. You could call this method "simulating".
Below is an example of how to accomplish this in the W3C DOM standard along with jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
This example is adapted from: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
In jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
But as of recently, there is no [DOM] way to actually trigger keyevents leaving the browser-sandbox. And all major browser vendors will adhere to that security concept.
As for plugins such as Adobe Flash - which are based on the NPAPI-, and permit bypassing the sandbox: these are phasing-out ; Firefox.
Detailed Explanation:
You cannot and you must not for security reasons (as Pekka already pointed out). You will always require a user interaction in between. Additionally imagine the chance of the browser vendors getting sued by users, as various programmatic keyboard events will have led to spoofing attacks.
See this post for alternatives and more details. There is always the flash based copy-and-paste. Here is an elegant example. At the same time it is a testimony why the web is moving away from plugin vendors.
There is a similar security mindset applied in case of the opt-in CORS policy to access remote content programmatically.
The answer is:
There is no way to programmatically trigger input keys in the sandboxed browser environment under normal circumstances.
Bottomline: I am not saying it will not be possible in the future, under special browser-modes and/or privileges towards the end-goal of gaming, or similar user-experiences. However prior to entering such modes, the user will be asked for permissions and risks, similar to the Fullscreen API model.
Useful: In the context of KeyCodes, this tool and keycode mapping will come in handy.
Disclosure: The answer is based on the answer here.
As of 2019, this solution has worked for me:
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
})
);
I used this in my browser game, in order to support mobile devices with a simulated keypad.
Clarification: This code dispatches a single keydown event, while a real key press would trigger one keydown event (or several of them if it is held longer), and then one keyup event when you release that key. If you need keyup events too, it is also possible to simulate keyup events by changing "keydown" to "keyup" in the code snippet.
This also sends the event to the entire webpage, hence the document. If you want only a specific element to receive the event, you can substitute document for the desired element.
You can use dispatchEvent():
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
I didn't test this, but it's adapted from the code on dispatchEvent()'s documentation. You'll probably want to read through that, and also the docs for createEvent() and initKeyEvent().
You can create and dispatch keyboard events, and they will trigger appropriate registered event handlers, however they will not produce any text, if dispatched to input element for example.
To fully simulate text input you need to produce a sequence of keyboard events plus explicitly set the text of input element. The sequence of events depends on how thoroughly you want to simulate text input.
The simplest form would be:
$('input').val('123');
$('input').change();
In some cases keypress event can't provide required funtionality. From mozilla docs we can see that the feature is deprecated:
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
So, since the keypress event is combined from the two consequently fired events keydown, and the following it keyup for the same key, just generate the events one-by-one:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
For those interested, you can, in-fact recreate keyboard input events reliably. In order to change text in input area (move cursors, or the page via an input character) you have to follow the DOM event model closely: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
The model should do:
focus (dispatched on the DOM with the target set)
Then for each character:
keydown (dispatched on the DOM)
beforeinput (dispatched at the target if its a textarea or input)
keypress (dispatched on the DOM)
input (dispatched at the target if its a textarea or input)
change (dispatched at the target if its a select)
keyup (dispatched on the DOM)
Then, optionally for most:
blur (dispatched on the DOM with the target set)
This actually changes the text in the page via javascript (without modifying value statements) and sets off any javascript listeners/handlers appropriately. If you mess up the sequence javascript will not fire in the appropriate order, the text in the input box will not change, the selections will not change or the cursor will not move to the next space in the text area.
Unfortunately the code was written for an employer under an NDA so I cannot share it, but it is definitely possible but you must recreate the entire key input "stack" for each element in the correct order.
Edit: I'm not the original poster of this answer, but I have tested it and I can't get it to work for updating an input field. Here's a code snippet with the code for others to try or review
let element = document.querySelector('input');
element.onkeydown = e => console.log('keydown on element: ' + e.key);
document.onkeydown = e => console.log('keydown on document: ' + e.key + " " + e.target);
dispatchButton.onclick = () => dispatchKey(element, 'a')
dispatchKey = (target, key) => {
let dom = document;
// focus (dispatched on the DOM with the target set)
let ev = new Event('focus', {target: target});
// this part seems to not work? when logging the
// target in the onkeypress function it shows `document` instead of `input`
// I also tried these and got the same behavior
// ev.target = target;
// and
// Object.defineProperty(ev, 'target', {writable: false, value: target});
dom.dispatchEvent(ev);
// keydown (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keydown', {'key': key, target: target}));
// beforeinput (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('beforeinput'));
// keypress (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keypress', {'key': key}));
// input (dispatched at the target if it's a textarea or input)
target.dispatchEvent(new Event('input'));
// change (dispatched at the target if it's a select)
// keyup (dispatched on the DOM)
dom.dispatchEvent(new KeyboardEvent('keyup', {'key': key}));
// Then, optionally for most:
// blur (dispatched on the DOM with the target set)
dom.dispatchEvent(new Event('blur', {target: target}));
console.log('dispatched');
}
<input/>
<button id="dispatchButton">Press to dispatch events </button>
Building on the answer from alex2k8, here's a revised version that works in all browsers that jQuery supports (the problem was in missing arguments to jQuery.event.trigger, which is easy to forget when using that internal function).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
You could even push this further and let it not only simulate the event but actually insert the character (if it is an input element), however there are many cross-browser gotcha's when trying to do that. Better use a more elaborate plugin like SendKeys.
just use CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex want to simulate ctrl+z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
This approach support cross-browser changing the value of key code.
Source
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
I wanted to simulate a 'Tab' press... Expanding on Trevor's answer, we can see that a special key like 'tab' does get pressed but we don't see the actual result which a 'tab' press would have...
tried with dispatching these events for 'activeElement' as well as the global document object both - code for both added below;
snippet below:
var element = document.getElementById("firstInput");
document.addEventListener("keydown", function(event) {
console.log('we got key:', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
/* enter is pressed */
if (event.keyCode == 13) {
console.log('enter pressed:', event);
theKey = 'Tab';
attributes = {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
};
setTimeout(function() {
/* event.keyCode = 13; event.target.value += 'b'; */
var e = new window.KeyboardEvent('focus', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.activeElement.dispatchEvent(e);
}, 4);
setTimeout(function() {
var e = new window.KeyboardEvent('focus', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('input', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('change', attributes);
document.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', attributes);
document.dispatchEvent(e);
}, 100);
} else if (event.keyCode != 0) {
console.log('we got a non-enter press...: :', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
}
});
<h2>convert each enter to a tab in JavaScript... check console for output</h2>
<h3>we dispatchEvents on the activeElement... and the global element as well</h3>
<input type='text' id='firstInput' />
<input type='text' id='secondInput' />
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()">
Click me to display Date and Time.</button>
<p id="demo"></p>
The critical part of getting this to work is to realize that charCode, keyCode and which are all deprecated methods. Therefore if the code processing the key press event uses any of these three, then it'll receive a bogus answer (e.g. a default of 0).
As long as you access the key press event with a non-deprecated method, such as key, you should be OK.
For completion, I've added the basic Javascript code for triggering the event:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
This worked for me and it does simulate a keyup for my textaera. if you want it for the entire page just put the KeySimulation() on <body> like this <body onmousemove="KeySimulation()"> or if not onmousemove then onmouseover or onload works too.
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Here's a library that really helps: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
I don't know from where did it came from, but it is helpful. It adds a .simulate() method to window.KeyEvent, so you use it simply with KeyEvent.simulate(0, 13) for simulating an enter or KeyEvent.simulate(81, 81) for a 'Q'.
I got it at https://github.com/ccampbell/mousetrap/tree/master/tests.
It was single rowed once due to easy usage in a console context. But probably useful still.
var pressthiskey = "q"/* <-- q for example */;
var e = new Event("keydown");
e.key = pressthiskey;
e.keyCode = e.key.charCodeAt(0);
e.which = e.keyCode;
e.altKey = false;
e.ctrlKey = true;
e.shiftKey = false;
e.metaKey = false;
e.bubbles = true;
document.dispatchEvent(e);
you can simulate input password with this code:
tested on chrome 100% work
DoCustomEvent('password', '#loginpin');
function DoCustomEvent(ct, elem){
var key;
var pressEvent = document.createEvent("CustomEvent");
pressEvent.initCustomEvent("keypress", true, false);
for (var i =0; i < ct.length; ++i)
{
key = ct.charCodeAt(i);
pressEvent.bubbles = true;
pressEvent.cancelBubble = false;
pressEvent.returnValue = true;
pressEvent.key = ct.charAt(i);
pressEvent.keyCode = key;
pressEvent.which = key;
pressEvent.charCode = key;
pressEvent.shiftKey = false;
pressEvent.ctrlKey = false;
pressEvent.metaKey = false;
document.querySelector(elem).focus();
//keypress //beforeinput //input //sendkeys //select
setTimeout(function() {
var e = new window.KeyboardEvent('keypress', pressEvent);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', pressEvent);
document.activeElement.dispatchEvent(e);
}, 0);
document.querySelector(elem).value = document.querySelector(elem).value + ct.charAt(i);
}
Here is a solution that works in Chrome and Chromium (have only tested these platforms). It seems Chrome has some bug or own approach to handling key codes so this property has to be added separately to the KeyboardEvent.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
simulateKeydown(39, false, false, false);
Native JavaScript with TypeScript supported solution:
Type the keyCode or whichever property you are using and cast it to KeyboardEventInit
Example
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
That's what I tried with js/typescript in chrome. Thanks to
this answer for inspiration.
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
{
// example
document.querySelector('input').addEventListener("keypress", e => console.log("keypress", e.key))
// unfortunatelly doesn't trigger submit
document.querySelector('form').addEventListener("submit", e => {
e.preventDefault();
console.log("submit")
})
}
var x = document.querySelector('input');
var keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
// you can try charCode or keyCode but they are deprecated
Object.defineProperty(keyboardEvent, "key", {
get() {
return "Enter";
},
});
x.dispatchEvent(keyboardEvent);
<form>
<input>
</form>
I know the question asks for a javascript way of simulating a keypress. But for those who are looking for a jQuery way of doing things:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Building on #aljgom's answer:
This worked great for me. Instead of dispatching the event to an element like aljgom had suggested, just dispatch it to the document.
document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));
as soon as the user presses the key in question you can store a reference to that even and use it on any HTML other element:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
you can set the keyCode if you create your own event, you can copy existing parameters from any real keyboard event (ignoring targets since its the job of dispatchEvent) and :
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
This is what I managed to find:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
Best way to js full screen toggle method:
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else if (document.exitFullscreen) {
document.exitFullscreen();
}
}