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应用程序的可怜的人。