如果你想要做正确的方式,你可以使用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})
Example
"map event.key to character values of a normal QUERTY (en-US) layout" proposal demo
注意键代码和则charCode在最新规格(WWW已被弃用.w3.org/TR/DOM级别-3-活动/)。所以Chrome没有机会实现initKeyEvent与keyCode的支持。但你总是可以覆盖该值: UPDATE:坏方法:
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) });
}
或者你可以更新事件原型:UPDATE:坏方法:
// 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填充工具我发现它在某种程度上是这样的(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);
}
}
}
我已经移除问题的意见,并把作为回答,因为我认为,甚至认为它并没有真正解决问题的,它可能是有同样的问题,像我一样的人真的很有帮助。 – fserb 2009-12-13 19:42:08
嘿,你是怎么解决这个问题的?我也面临着模拟铬/ safari左右按键的问题。但没有成功,你是怎么做到的? – MaX 2013-01-15 00:50:16
您是否尝试过我发布的解决方案?它对我有用,可能会帮助你实现你的目标,所以你接受你自己的“这是一个bug”的答案对我来说很奇怪。 – Dennis 2014-07-02 17:53:51