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


当前回答

基于@aljgom的回答:

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

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

其他回答

你可以在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的页面,这是一个尝试模拟键盘行为的线程

我知道这个问题要求一个javascript的方式来模拟一个按键。但是对于那些正在寻找jQuery方法的人来说:

var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e); 

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

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

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

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

截至2019年,这个解决方案对我来说是有效的:

document.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.
  })
);

为了支持带有模拟键盘的移动设备,我在自己的浏览器游戏中使用了这种方法。

澄清:这段代码分派一个keydown事件,而真正的按键将触发一个keydown事件(如果按住时间较长,则会触发多个keydown事件),然后在释放该键时触发一个keyup事件。如果您也需要keyup事件,也可以通过在代码片段中将“keydown”更改为“keyup”来模拟keyup事件。

这也会将事件发送到整个网页,也就是文档。如果只希望特定元素接收事件,可以用document代替所需元素。

您所能做的就是通过触发键事件以编程方式触发keyevent侦听器。从沙盒安全的角度来看,允许这样做是有意义的。使用此功能,您可以应用典型的观察者模式。您可以将此方法称为“模拟”。

下面是如何在W3C DOM标准和jQuery中实现这一点的示例:

function triggerClick() {
  var event = new MouseEvent('click', {
    'view': window,
    'bubbles': true,
    'cancelable': true
  });
  var cb = document.querySelector('input[type=submit][name=btnK]'); 
  var canceled = !cb.dispatchEvent(event);
  if (canceled) {
    // preventDefault was called and the event cancelled
  } else {
    // insert your event-logic here...
  }
}

此示例改编自:https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

jQuery:

jQuery('input[type=submit][name=btnK]')
  .trigger({
    type: 'keypress',
    which: character.charCodeAt(0 /*the key to trigger*/)      
   });

但是到目前为止,还没有[DOM]方法来触发离开浏览器沙箱的键事件。所有主要的浏览器供应商都将遵循这一安全概念。

至于Adobe Flash等基于NPAPI的插件,允许绕过沙盒:这些插件正在逐步淘汰;Firefox。

详细解释:

出于安全原因(正如Pekka已经指出的),您不能也不应该这样做。在两者之间总是需要用户交互。此外,想象一下浏览器供应商被用户起诉的可能性,因为各种编程键盘事件将导致欺骗攻击。

有关替代方案和更多细节,请参阅这篇文章。总是有基于flash的复制粘贴。这里有一个很好的例子。同时,它也证明了为什么网络正在远离插件供应商。

在选择加入CORS策略以编程方式访问远程内容的情况下,也应用了类似的安全思想。

答案是: 在正常情况下,在沙箱浏览器环境中无法以编程方式触发输入键。

底线:我并不是说在未来,在特殊的浏览器模式和/或游戏最终目标的特权下,这是不可能的,或类似的用户体验。然而,在进入这些模式之前,用户将被询问权限和风险,类似于全屏API模型。

有用:在KeyCodes上下文中,此工具和键码映射将派上用场。

披露:答案是基于这里的答案。