我正在尝试使用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.尽管如此,我仍然无法使其成功.
我也尝试过这里描述的JQuery方法但没有成功.
编辑: 我进一步调试了这一点似乎Chrome上的事件确实触发了侦听器,但keyCode/charCode始终为0.我试图设置evt.keyCode或evt.charCode也没有成功.
我已经跟踪了Webkit上的一个错误,其中创建的事件只包含KeyIdentifier但没有keyCode/charCode,这可以在浏览器源代码中看到.似乎有一个补丁正在解决这个问题.所以我想这不再是一个正确的问题......
如果您想以正确的方式执行此操作,则可以使用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})
例
"将event.key映射到正常QUERTY(en-US)布局"提案演示的字符值
请注意,最新的Spec(www.w3.org/TR/DOM-Level-3-Events/)中不推荐使用keyCode和charCode.因此,Chrome 无法通过keyCode支持实现initKeyEvent.但是你总是可以覆盖这个值: 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) }); }
或者您可以更新事件原型:更新:错误的方法:
// 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 ); } } }
我只想把这个基本片段扔出去.它适用于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);