是否可以在JavaScript中以编程方式模拟按键事件?


当前回答

这对我来说是有效的,它确实为我的textaera模拟了一个按键。如果你想在整个页面中使用它,只需将KeySimulation()放在<body>上,就像这样<body onmousemove="KeySimulation()“>或如果不是onmousemove,那么onmouseover或onload也可以。

function KeySimulation() { var e = document.createEvent("KeyboardEvent"); if (e.initKeyboardEvent) { // Chrome, IE e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, ""); } else { // FireFox e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0); } document.getElementById("MyTextArea").dispatchEvent(e); } <input type="button" onclick="KeySimulation();" value=" Key Simulation " /> <textarea id="MyTextArea" rows="15" cols="30"></textarea>

其他回答

您可以创建和分派键盘事件,它们将触发相应的已注册事件处理程序,但是,如果分派到input元素,则不会产生任何文本。

要完全模拟文本输入,您需要生成一系列键盘事件,并显式地设置input元素的文本。事件的顺序取决于模拟文本输入的彻底程度。

最简单的形式是:

$('input').val('123');
$('input').change();

对于那些感兴趣的人,您可以可靠地重新创建键盘输入事件。为了更改输入区域中的文本(移动游标,或通过输入字符移动页面),必须严格遵循DOM事件模型:http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents

该模型应该做到:

焦点(使用目标设置在DOM上分派)

然后对于每个字符:

keydown(在DOM上分派) Beforeinput(如果它是一个文本区域或输入,在目标分派) 按键(在DOM上分派) 输入(如果是文本区域或输入,则在目标处分派) 改变(如果它是一个选择,在目标分派) keyup(在DOM上分派)

然后,可选的大多数:

模糊(随目标设置在DOM上分派)

这实际上是通过javascript改变页面中的文本(不修改值语句),并适当地设置任何javascript侦听器/处理程序。如果你把顺序弄乱了,javascript就不会按适当的顺序触发,输入框中的文本不会改变,选择不会改变,或者光标不会移动到文本区域的下一个空格。

不幸的是,代码是为雇主写的,所以我不能分享它,但这绝对是可能的,但你必须以正确的顺序为每个元素重新创建整个关键输入“堆栈”。


编辑:我不是这个答案的原始海报,但我已经测试过了,我不能让它更新输入字段。下面是一个代码片段,其中的代码供其他人尝试或查看

let element = document.querySelector('input'); element.onkeydown = e => console.log('keydown on element: ' + e.key); document.onkeydown = e => console.log('keydown on document: ' + e.key + " " + e.target); dispatchButton.onclick = () => dispatchKey(element, 'a') dispatchKey = (target, key) => { let dom = document; // focus (dispatched on the DOM with the target set) let ev = new Event('focus', {target: target}); // this part seems to not work? when logging the // target in the onkeypress function it shows `document` instead of `input` // I also tried these and got the same behavior // ev.target = target; // and // Object.defineProperty(ev, 'target', {writable: false, value: target}); dom.dispatchEvent(ev); // keydown (dispatched on the DOM) dom.dispatchEvent(new KeyboardEvent('keydown', {'key': key, target: target})); // beforeinput (dispatched at the target if it's a textarea or input) target.dispatchEvent(new Event('beforeinput')); // keypress (dispatched on the DOM) dom.dispatchEvent(new KeyboardEvent('keypress', {'key': key})); // input (dispatched at the target if it's a textarea or input) target.dispatchEvent(new Event('input')); // change (dispatched at the target if it's a select) // keyup (dispatched on the DOM) dom.dispatchEvent(new KeyboardEvent('keyup', {'key': key})); // Then, optionally for most: // blur (dispatched on the DOM with the target set) dom.dispatchEvent(new Event('blur', {target: target})); console.log('dispatched'); } <input/> <button id="dispatchButton">Press to dispatch events </button>

下面是一个在Chrome和Chromium上工作的解决方案(只测试了这些平台)。似乎Chrome有一些错误或自己的方法来处理关键代码,所以这个属性必须单独添加到KeyboardEvent。

函数simulateKeydown (keycode, istrl,isAlt,isShift){ var e = new KeyboardEvent("keydown",{冒泡泡:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt}); Object.defineProperty(e, 'keyCode', {get: function(){返回this.keyCodeVal;}}); e.keyCodeVal = keycode; document.dispatchEvent (e); } simulateKeydown(39, false, false, false);

在某些情况下,按键事件不能提供所需的功能。从mozilla文档中我们可以看到该特性已被弃用:

不再推荐使用此特性。虽然一些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除了,可能正在被删除的过程中,或者可能只是为了兼容性的目的而保留。避免使用它,并尽可能更新现有代码;请参阅本页底部的兼容性表,以指导您的决定。请注意,此功能可能在任何时候停止工作。

因此,由于按键事件是由两个随后触发的事件keydown和接下来的同一个按键的keyup组合而成的,只需一个接一个地生成事件:

element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));

一个非jquery版本,工作在webkit和gecko:

var keyboardEvent = document.createEvent('KeyboardEvent'); var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent'; keyboardEvent[initMethod]( 'keydown', // event type: keydown, keyup, keypress true, // bubbles true, // cancelable window, // view: should be window false, // ctrlKey false, // altKey false, // shiftKey false, // metaKey 40, // keyCode: unsigned long - the virtual key code, else 0 0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0 ); document.dispatchEvent(keyboardEvent);