我正在尝试使用Chrome上的javascript将键盘事件发送到页面。 我有一种过去常用于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);
}
其中key是所需的键,keyCode将小写字母更改为高位字母,并且还调用charCodeAt()。
我的问题是Safari / Chrome上的事件没有initKeyEvent,而是initKeyboardEvent。我可以注意到的主要区别是你必须将密钥作为keyIdentifier(看起来像一个unicode字符)传递,而不是传递keycode和keychar。尽管如此,我仍然无法使其发挥作用。
我还尝试了here描述的JQuery方法但没有成功。
修改 我进一步调试了这一点,似乎Chrome上的事件确实触发了侦听器,但keyCode / charCode始终为0.我试图设置evt.keyCode或evt.charCode也没有成功。
答案 0 :(得分:19)
我已将其跟踪到bug on Webkit,其中创建的事件仅包含KeyIdentifier,但没有browser source code上可见的keyCode / charCode。似乎有一个补丁正在解决这个问题。所以我想这不再是一个正确的问题......
答案 1 :(得分:11)
如果您想以正确的方式进行,可以使用DOM 键盘事件级别4 KeyboardEvent构造和键属性。
在最新的浏览器中或使用DOM Keyboard Event Level 3/4 polyfill,您可以执行以下操作:
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})
"map event.key to character values of a normal QUERTY (en-US) layout" proposal demo
请注意,最新的Spec(www.w3.org/TR/DOM-Level-3-Events/)中不推荐使用 keyCode 和 charCode 。因此Chrome无法通过 keyCode 支持实施 initKeyEvent 。但是你总是可以覆盖这个值: 更新:错误方法:
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) });
}
或者您可以更新事件原型:更新:错误方法:
// 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;
}
});
<强>更新强> initKeyboardEvent有各种实现。在我的KeyboardEvent polyfill中,我以某种方式检测它(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 );
}
}
}
答案 2 :(得分:5)
我只是想把这个基本片段扔出去。它适用于Chrome,基于Paul Irish提到的黑客攻击 它使用charCode而不是keyCode(在某些情况下可能很有用),但如果您愿意,请使用keyCode。
var keyboardEvent = new KeyboardEvent('keypress', {bubbles:true});
Object.defineProperty(keyboardEvent, 'charCode', {get:function(){return this.charCodeVal;}});
keyboardEvent.charCodeVal = [your char code];
document.body.dispatchEvent(keyboardEvent);
答案 3 :(得分:2)
根据您的需要,TextEvent可能会起作用。 (它适合我的需要 - 对于chrome。这不是跨浏览器测试,但是,问题是关于chrome的。)
// get a reference to the DOM element you want to affect
var input = document.getElementsByTagName('input')[0];
// create a TextEvent
var textEvent = document.createEvent('TextEvent');
// initialize the TextEvent
textEvent.initTextEvent('textInput', true, true, null, String.fromCharCode(13)+"\r\n", 9, "en-US");
// dispatch ('fire') the TextEvent
input.dispatchEvent(textEvent);
答案 4 :(得分:2)
您可以使用createEvent('Event')
而不是createEvent('KeyboardEvent')
解决Webkit错误,然后分配keyCode
属性。请参阅this answer和this example。