I'm trying to simulate a keyboard event in Safari using JavaScript.

I have tried this:

var event = document.createEvent("KeyboardEvent");
event.initKeyboardEvent("keypress", true, true, null, false, false, false, false, 115, 0);

...and also this:

var event = document.createEvent("UIEvents");
event.initUIEvent("keypress", true, true, window, 1);
event.keyCode = 115;

After trying both approaches, however, I have the same problem: after the code has been executed, the keyCode/which properties of the event object are set to 0, not 115.

Does anyone know how to reliably create and dispatch a keyboard event in Safari? (I'd prefer to achieve it in plain JavaScript if possible.)

share|improve this question
    
Are you trying to execute code you have defined or some key-combination the browser understands? If it's your own code, it might be best to setup an event wrapper that you can either call via a "real" keyboard interface or via some other event generator, as you have described here. Refactoring as appropriate. – Nolte Jun 7 '09 at 8:55
1  
In this example, I'm trying to simulate the user pressing "s". Ultimately, I'm trying to simulate the user pressing Command-R in an Apple Dashboard Widget. – Steve Harrison Jun 7 '09 at 9:08
2  
Your code solved my problem :) – acidzombie24 Jan 18 '11 at 14:45
    
@acidzombie24: My pleasure! :) – Steve Harrison Jan 19 '11 at 0:35
1  
Duplicate of Simulate JavaScript Key Events – Dan Dascalescu Sep 2 '15 at 6:12

Did you dispatch the event correctly?

function simulateKeyEvent(character) {
  var evt = document.createEvent("KeyboardEvent");
  (evt.initKeyEvent || evt.initKeyboardEvent)("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0)) 
  var canceled = !body.dispatchEvent(evt);
  if(canceled) {
    // A handler called preventDefault
    alert("canceled");
  } else {
    // None of the handlers called preventDefault
    alert("not canceled");
  }
}

If you use jQuery, you could do:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}
share|improve this answer
    
Seems to be there's a mistake in the line: evt.initKeyEvent. In Chromium I don't have method initKeyEvent in KeyboardEvent.prototype. For me it has to be: evt.initKeyboardEvent – gvlasov Jul 23 '12 at 3:24
3  
Is it possible to simulate control + C (copy shortcut) with this? – John John Pichler Jan 22 '13 at 23:23
    
@EdPichler There is a special API for interacting with the pasteboard, I would't do it the hard way by simulating a keyboard event. Related SO post – 11684 Jan 30 '13 at 15:47
1  
@claudiopro Yes, you are correct it should be (evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc. – tyronegcarter Feb 18 '14 at 18:57
6  
The initKeyboardEvent doesn't work in Chromium either. event.keyCode and event.whichalways return 0. It's a known bug and the workaround is to use a regular event var event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76; – lluft Jan 6 '15 at 20:38

I am working on DOM Keyboard Event Level 3 polyfill . In latest browsers or with this polyfill you can do something like this:

element.addEventListener("keydown", function(e){ console.log(e.key, e.char, e.keyCode) })

var e = new KeyboardEvent("keydown", {bubbles : true, cancelable : true, key : "Q", char : "Q", shiftKey : true});
element.dispatchEvent(e);

//If you need legacy property "keyCode"
// Note: In some browsers you can't overwrite "keyCode" property. (At least in Safari)
delete e.keyCode;
Object.defineProperty(e, "keyCode", {"value" : 666})

UPDATE:

Now my polyfill supports legacy properties "keyCode", "charCode" and "which"

var e = new KeyboardEvent("keydown", {
    bubbles : true,
    cancelable : true,
    char : "Q",
    key : "q",
    shiftKey : true,
    keyCode : 81
});

Examples here

Additionally here is cross-browser initKeyboardEvent separately from my polyfill: (gist)

Polyfill demo

share|improve this answer
    
Doesn't seem to work for making a scrollable area scroll down using arrow or page up/down keys... – Michael Apr 16 '15 at 6:01
    
Changed your jsfiddle to dispatch the event on textbox instead of document @ jsfiddle.net/vnathalye/yjc5F/974. Though it fires the keypress handler, the text doesn't get displayed in textbox. Any idea? – Vivek Athalye Jan 18 at 5:32
    
@termi Your demo link is dead – Sebastian Mar 16 at 11:16
    
Doesn't seem to work for changing the value of an input (text) element either. – Michael Apr 21 at 23:44

This is due to a bug in Webkit.

You can work around the Webkit bug using createEvent('Event') rather than createEvent('KeyboardEvent'), and then assigning the keyCode property. See this answer and this example.

share|improve this answer

The Mozilla Developer Network provides the following explanation:

  1. Create an event using event = document.createEvent("KeyboardEvent")
  2. Init the keyevent

using:

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)
  1. Dispatch the event using yourElement.dispatchEvent(event)

I don't see the last one in your code, maybe that's what you're missing. I hope this works in IE as well...

share|improve this answer
2  
Unfortunately, this doesn't fix the problem. – Steve Harrison Jun 7 '09 at 9:07
    
I revised my whole answer, hope that helps. – Javache Jun 7 '09 at 9:40
1  
Unfortunately, Mozilla's implementation is non-standard. As for point 3, my problem is creating the correct event—dispatching the event comes after this. Also, since I'm developing for Apple's Dashboard, I don't have to worry about IE at all! (Whoopee!) – Steve Harrison Jun 8 '09 at 1:19
    
.initKeyEvent is now deprecated – Hampus Ahlgren Aug 18 '16 at 19:56

I am not very good with this but KeyboardEvent => see KeyboardEvent is initialized with initKeyEvent .
Here is an example for emitting event on <input type="text" /> element

document.getElementById("txbox").addEventListener("keypress", function(e) {
  alert("Event " + e.type + " emitted!\nKey / Char Code: " + e.keyCode + " / " + e.charCode);
}, false);

document.getElementById("btn").addEventListener("click", function(e) {
  var doc = document.getElementById("txbox");
  var kEvent = document.createEvent("KeyboardEvent");
  kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74);
  doc.dispatchEvent(kEvent);
}, false);
<input id="txbox" type="text" value="" />
<input id="btn" type="button" value="CLICK TO EMIT KEYPRESS ON TEXTBOX" />

share|improve this answer
5  
it shows js:21TypeError: kEvent.initKeyEvent is not a function. (In 'kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74)', 'kEvent.initKeyEvent' is undefined) in safari :( – Arefly Oct 20 '15 at 11:50
    
In current version of Chrome (52) I got error:Uncaught TypeError: kEvent.initKeyEvent is not a function – Sergey P. aka azure Aug 23 '16 at 14:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.