Chrome中的Keydown Simulation通常会触发但不是正确的键

我想模拟html页面中给定textarea元素上的keydown事件。 由于我使用的是chrome,因此我在我的variables上调用了initKeyboardEvent ,并将我想要键入的keyCode传递给textarea。 这是我试过的:

 var keyEvent = document.createEvent('KeyboardEvent'); keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0); inputNode.dispatchEvent(keyEvent); 

在这个代码中,我input了字母m但是textarea只是获得了Enter键的keyCode 13 。 所以,我尝试了一个覆盖的代码,我看到在线设置值keyCodeVal,但没有成功

 var keyEvent = document.createEvent('KeyboardEvent'); Object.defineProperty(keyEvent, 'keyCode', { get : function() { return this.keyCodeVal; } }); keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0); keyEvent.keyCodeVal = 77; inputNode.dispatchEvent(keyEvent); 

有没有人有一个想法如何设置keyCode值?

非常非常近

你只需要重写'which'属性。 以下是一些示例代码:

 Podium = {}; Podium.keydown = function(k) { var oEvent = document.createEvent('KeyboardEvent'); // Chromium Hack Object.defineProperty(oEvent, 'keyCode', { get : function() { return this.keyCodeVal; } }); Object.defineProperty(oEvent, 'which', { get : function() { return this.keyCodeVal; } }); if (oEvent.initKeyboardEvent) { oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, k, k); } else { oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, k, 0); } oEvent.keyCodeVal = k; if (oEvent.keyCode !== k) { alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")"); } document.dispatchEvent(oEvent); } 

示例用法:

 Podium.keydown(65); 

注意:此代码不适用于IE,Safari或其他浏览器。 那么,也许与Firefox。 因人而异。

Orwellophile的解决scheme确实有效。

  • 首先:“keyCode”,“charCode”和“which”在Safari和IE9 +(至less)中是只读的。
  • 第二:initKeyboardEvent是一种凌乱。 所有浏览器都以不同的方式实现它。 即使在webkit中也有几个不同的initKeyboardEvent实现。 在Opera中没有“好”的initKeyboardEvent方法。
  • 第三:不推荐使用initKeyboardEvent。 您需要使用initKeyEvent或KeyboardEvent构造函数。

在这里我写了一个跨浏览器的initKeyboardEvent函数 (gist):

例:

 var a = window.crossBrowser_initKeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true}) alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey) 

这里是我的DOM键盘事件3级填充与跨浏览器的KeyboardEvent构造函数。

例:

 var a = new KeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true}) alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey) 

例2

例3

重要注意1:charCode,keyCode和哪些属性已被弃用。 因此,我的crossBrowser_initKeyboardEvent无KeyboardEvent构造函数绝对保证在某些浏览器中该属性的正确值。 你可以使用属性“key”和“char”来代替,或者编辑我的要点 ,在只读charCode,keyCode和哪些属性的浏览器中强制使用initEvent。

重要说明2:keypress事件已弃用,现在在我的键盘事件3级填充中不受支持。 这意味着keypress事件中的键和char属性可以具有随机值。 我正在努力解决这个问题,以向后兼容。

为了让@Overwellophile的脚本可以在Google Chrome 26.0.1410.65上运行(在Mac OS X 10.7.5上,如果有的话),我必须改变一行:他的脚本似乎有不同于initKeyboardEvent的顺序initKeyboardEvent的MDN文档 。

改变的行看起来像这样:

 oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, k, k, "", "", false, ""); 

那么上面的解决scheme确实工作,还要感谢@dland参数提示。 如果你不能在正确的地方开火,我觉得这是有用的。

@ Orwellophile的脚本在文档上触发事件。 事件监听器可能不总是在document注册。 我把最后一行改成了下一个,现在每次都很有效。

document.activeElement.dispatchEvent(oEvent);

document.activeElement总是在用户当前关注的元素上触发事件。

以上所有的解决scheme都在工作,但我发现他们不会的一个案例。

如果使用Dart,则使用KeyboardEvent的Dart代码将无法在一般Event上使用。

你会得到像$ keyCode未定义的东西。

在我敲了几个小时之后,我发现了以下的技巧:

 function __triggerKeyboardEvent(el, keyCode) { var eventObj = document.createEventObject ? document.createEventObject() : document.createEvent("Events"); var tempKeyboardObj = document.createEvent("KeyboardEvents"); if(eventObj.initEvent){ eventObj.initEvent("keydown", true, true); } eventObj.___dart_dispatch_record_ZxYxX_0_ = tempKeyboardObj.___dart_dispatch_record_ZxYxX_0_ eventObj.keyCode = keyCode; eventObj.which = keyCode; el.dispatchEvent ? el.dispatchEvent(eventObj) : el.fireEvent("onkeydown", eventObj); } 

愚蠢的飞镖拦截器事件我们的事实上是一个KeyboardEvent,做了诡计。

把它留在这里,对于试图在基于webkit的浏览器上testingDart应用程序的可怜的人。