I'm trying to fire a keyboard event to a page using javascript on Chrome. I had an approach that used to work on Firefox:
pressKey = function(key, shift) { var evt = document.createEvent('KeyboardEvent'); evt.initKeyEvent("keypress", false, true, null, false, false, shift, false, keyCode(key), key.charCodeAt(0)); document.dispatchEvent(evt); }
where key is the desired key and keyCode changes lowercase letters into highercase and also calls charCodeAt().
My problem is that events on Safari/Chrome don't have initKeyEvent, but initKeyboardEvent. The main difference I could notice was that you have to pass the key as a keyIdentifier (which looks like a unicode character) instead of passing the keycode and the keychar. Nonetheless I still can't manage to make it work.
I've also tried the JQuery approach described here without success.
EDIT: I debugged this a little further and it seems that the event on Chrome does trigger the listeners, but keyCode/charCode is always 0. I've tried to set evt.keyCode or evt.charCode with no success either.
keydown: This event is triggered when a key is pressed down. keypress: This event is triggered when a key is pressed. This event fails to recognise keys such as tab, shift, ctrl, backspace etc. keyup: This event is triggered when a key is released.
There are three types of keyboard events: keydown , keypress , and keyup .
The keydown event is fired when a key is pressed. Unlike the keypress event, the keydown event is fired for all keys, regardless of whether they produce a character value.
Explanation: The keydown and keyup are the keyboard events are fired when the user presses or releases a key on the keyboard. They are generated for modifier keys, function keys, and alphanumeric keys. 2.
I've tracked this down to a bug on Webkit where created events only contain KeyIdentifier but no keyCode/charCode as can be seen on the browser source code. There seems to be a patch going on to solve this. So I guess this is not a proper question anymore...
If you want do it in the right way, you can use DOM Keyboard Event Level 4 KeyboardEvent construct and key property.
In latest browsers or with DOM Keyboard Event Level 3/4 polyfill you can do something like this:
element.addEventListener(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})
Example
"map event.key to character values of a normal QUERTY (en-US) layout" proposal demo
Note that keyCode and charCode are deprecated in latest Spec (www.w3.org/TR/DOM-Level-3-Events/). So the is no chance to Chrome to implement initKeyEvent with keyCode support. But you can always override this value: UPDATE: bad method:
var evt = document.createEvent('KeyboardEvent'); evt.initKeyEvent("keypress", false, true, null, false, false, shift, false, keyCode(key), key.charCodeAt(0)); if(evt.keyCode != keyCode(key)) { delete evt.keyCode; // Note: In some browsers you can't overwrite "keyCode" property. (At least in Safari) Object.defineProperty(evt, "keyCode", { keyCode(key) }); }
Or you can update event prototype: UPDATE: bad method:
// Note: In some browsers you can't overwrite "keyCode" property. (At least in Safari) var _native_keyCode_getter = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, "keyCode"); Object.defineProperty(KeyboardEvent.prototype, "keyCode", { "enumerable" : true, "configurable" : true, "get" : function() { if("__keyCode" in this)return this["__keyCode"]; return _native_keyCode_getter.call(this); }, "set" : function(newValue) { return this["__keyCode"] = isNaN(newValue) ? 0 : newValue; } });
Update There are various implementation of initKeyboardEvent. In my KeyboardEvent polyfill I detect it somehow like this (gist):
var _initKeyboardEvent_type = (function( e ) { try { e.initKeyboardEvent( "keyup" // in DOMString typeArg , false // in boolean canBubbleArg , false // in boolean cancelableArg , global // in views::AbstractView viewArg , "+" // [test]in DOMString keyIdentifierArg | webkit event.keyIdentifier | IE9 event.key , 3 // [test]in unsigned long keyLocationArg | webkit event.keyIdentifier | IE9 event.location , true // [test]in boolean ctrlKeyArg | webkit event.shiftKey | old webkit event.ctrlKey | IE9 event.modifiersList , false // [test]shift | alt , true // [test]shift | alt , false // meta , false // altGraphKey ); return ((e["keyIdentifier"] || e["key"]) == "+" && (e["keyLocation"] || e["location"]) == 3) && ( e.ctrlKey ? e.altKey ? // webkit 1 : 3 : e.shiftKey ? 2 // webkit : 4 // IE9 ) || 9 // FireFox|w3c ; } catch ( __e__ ) { alert("browser do not support KeyboardEvent") } })( document.createEvent( "KeyboardEvent" ) ); var e = document.createEvent( "KeyboardEvent" ); ... if( "initKeyEvent" in e ) {//FF //https://developer.mozilla.org/en/DOM/event.initKeyEvent e.initKeyEvent( type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _keyCode ); } else if( "initKeyboardEvent" in e ) {//https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent() if( _try_initKeyboardEvent ) { if( _initKeyboardEvent_type == 1 ) { // webkit //http://stackoverflow.com/a/8490774/1437207 //https://bugs.webkit.org/show_bug.cgi?id=13368 e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _shiftKey, _altKey, _metaKey, _altGraphKey ); } else if( _initKeyboardEvent_type == 2 ) { // old webkit //http://code.google.com/p/chromium/issues/detail?id=52408 e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _keyCode ); } else if( _initKeyboardEvent_type == 3 ) { // webkit e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _altKey, _shiftKey, _metaKey, _altGraphKey ); } else if( _initKeyboardEvent_type == 4 ) { // IE9 //http://msdn.microsoft.com/en-us/library/ie/ff975297(v=vs.85).aspx e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _modifiersListArg, _repeat, _locale ); } else { // FireFox|w3c //http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent-initKeyboardEvent //https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent() e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _char, _key, _location, _modifiersListArg, _repeat, _locale ); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With