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


当前回答

基于@aljgom的回答:

这对我来说很有效。而不是像aljgom建议的那样将事件分派给元素,而是将它分派给文档。

document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));

其他回答

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

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

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

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

你可以在EventTarget(元素,窗口,文档等)上分派键盘事件,如下所示:

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

但是,dispatchEvent可能不会更新输入字段值,也可能不会触发常规键盘按下的行为,这可能是因为Event的原因。itrusted property,我不知道是否有办法绕过

但是你也可以通过设置输入值来改变输入。

element.value += "a";

例子:

let element = document.querySelector('input'); 元素。Onkeydown = e =>警报(e.key); changeValButton。Onclick =() =>元素。Value += "a"; dispatchButton。Onclick = () => { 元素。dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'})); } <输入/ > <button id="dispatchButton">按下分派事件</button> <button id="changeValButton">按下按钮更改值</button> . </button id="changeValButton">


您可以根据需要向事件添加更多属性,如本答案所示。看一下KeyboardEvent文档

element.dispatchEvent(new KeyboardEvent("keydown", {
    key: "e",
    keyCode: 69, // example values.
    code: "KeyE", // put everything you need in this object.
    which: 69,
    shiftKey: false, // you don't need to include values
    ctrlKey: false,  // if you aren't going to use them.
    metaKey: false   // these are here for example's sake.
}));

    

此外,由于keypress已弃用,您可以使用keydown + keyup,例如:

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

对于使用ReactJS的页面,这是一个尝试模拟键盘行为的线程

下面是一个在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);

对于那些感兴趣的人,您可以可靠地重新创建键盘输入事件。为了更改输入区域中的文本(移动游标,或通过输入字符移动页面),必须严格遵循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>

如果你可以使用jQuery 1.3.1:

函数simulateKeyPress(字符){ jQuery.event.trigger ({ 类型:键盘按键, 其中:character.charCodeAt (0) }); } $(函数(){ 美元(的身体).keypress(函数(e) { 警报(e.which); }); simulateKeyPress(“e”); }); < script src = " https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js " > > < /脚本