Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firing a keyboard event on Chrome

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.

like image 939
fserb Avatar asked Dec 13 '09 18:12

fserb


People also ask

How do I trigger an event on my keyboard?

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.

What are the events of keyboard?

There are three types of keyboard events: keydown , keypress , and keyup .

Which event is triggered when you click any key on the keyboard?

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.

Which of following event is generated when input is received from keyboard?

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.


2 Answers

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...

like image 188
fserb Avatar answered Sep 18 '22 15:09

fserb


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 );         }     } } 
like image 37
termi Avatar answered Sep 16 '22 15:09

termi