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

IT技术 javascript dom-events
2020-12-30 16:45:27

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

6个回答

适用于 webkit 和 gecko 的非 jquery 版本:

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);

事实证明,Chromium 中有一个带有 KeyboardEvent 调度的错误。看看这个线程的详细信息:stackoverflow.com/questions/10455626/...
2021-02-07 16:45:27
好像现在这个功能已经被移除了。不过,MDN 认为它已经弃用了很长时间。
2021-02-21 16:45:27
keyCode 始终为 0,我无法更改它。
2021-02-27 16:45:27
菲利普,这看起来像我需要的代码,但我需要将按键事件分派到文本区域。我试图修改您的代码以发送到 textarea,但它似乎不起作用,至少在 chrome 中,不知道有什么问题?这是我用来演示的jsfiddlejsfiddle.net/szmJu
2021-03-06 16:45:27
看来,有一个在铬引起的错误event.which永远是0当使用document.createEvent("KeyboardEvent")@lluft在另一个线程的评论中分享了对我有用的细节和解决方法基本上,您需要使用document.createEvent('Event')来创建一个通用事件,然后将类型设置为keydown并赋予一个keyCode与键的字符码相等的属性。
2021-03-09 16:45:27

如果您可以使用 jQuery 1.3.1:

function simulateKeyPress(character) {
  jQuery.event.trigger({
    type: 'keypress',
    which: character.charCodeAt(0)
  });
}

$(function() {
  $('body').keypress(function(e) {
    alert(e.which);
  });
  simulateKeyPress("e");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>

2021-02-13 16:45:27
它在 Chrome 中无法正常工作,抱歉。jQuery 创建事件,但没有重要的属性——which、charCode、keyCode。
2021-02-28 16:45:27
嗨我的意思是:1.注册一个关键事件(字母e执行一些JS)2.从另一种方法我想以编程方式按下字母e)
2021-03-01 16:45:27
@tan 这是不可能的。请参阅我的答案以了解其背后的原因。
2021-03-08 16:45:27

您可以像这样在元素上调度键盘事件:

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

但是,dispatchEvent可能不会更新输入字段值。此外,它可能不会触发常规键盘按下的行为,可能是因为Event.isTrusted属性,我不知道是否有办法绕过


例子:

let element = document.querySelector('input');
element.onkeydown = e => alert(e.key);
element.dispatchEvent(new KeyboardEvent('keydown', {
  'key': 'a'
}));
<input/>


您可以根据需要向事件添加更多属性,例如这个答案看一下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'} ));
我认为这个答案应该提到在 js 事件中调度不会更新输入内容的事实。
2021-02-08 16:45:27
似乎keypress已折旧,keydown改为使用-> developer.mozilla.org/en-US/docs/Web/Events/keypress
2021-02-11 16:45:27
根据我的需要,它非常适合我使用 Chrome Embedded。
2021-02-24 16:45:27
最新的 Firefox 不现代?
2021-03-05 16:45:27

您可以做的是通过触发keyevents编程方式触发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] 方法来实际触发离开浏览器沙箱的键事件。所有主要的浏览器供应商都将坚持这一安全理念。

至于诸如 Adob​​e Flash 之类的插件——它们基于 NPAPI——并允许绕过沙箱:这些正在逐步淘汰火狐

详细说明:

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

有关替代方案和更多详细信息,请参阅此帖子总是有基于闪存的复制和粘贴。这是一个优雅的 例子同时,这也证明了为什么网络正在远离插件供应商。

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

答案是:
一般情况下,在沙盒浏览器环境中没有办法以编程方式触发输入键

底线:我并不是说在特殊的浏览器模式和/或实现游戏最终目标的特权或类似的用户体验下,将来不可能实现。但是,在进入此类模式之前,将要求用户提供权限和风险,类似于Fullscreen API 模型

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

披露:答案基于此处的答案

这是我在 Chrome 中运行 jQuery 时得到的结果:Uncaught ReferenceError: character is not defined
2021-02-16 16:45:27
因此,使用 JavaScript KeyboardEvent API ( developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent ),您可以模拟按键事件,例如,按键被按下但不可能有按键效果, 喜欢写字符 'a', 'b', 'c'?如果可能的话,写这些基本字符不是安全问题,但我知道应该禁止使用像“F12”这样的特殊键或像“Alt+F4”这样的组合。
2021-02-23 16:45:27
披露您的意思是“免责条款”?
2021-03-04 16:45:27

截至 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事件(如果按住时间更长,则会触发多个事件),然后keyup在您释放该键时触发一个事件如果您也需要keyup事件,也可以keyup通过在代码片段中更改"keydown"来模拟事件"keyup"

这也会将事件发送到整个网页,因此document. 如果您只希望特定元素接收事件,则可以替换document所需元素。

@hanshenrik - 说实话,如果你在 2020 年使用 Flash,你真的需要重新考虑哪些工具最适合你的目的。
2021-02-13 16:45:27
由于某种原因,Flash 游戏完全忽略了(也许 Flash 忽略了所有不是Trusted?)
2021-02-28 16:45:27
请让 Flash 死去
2021-03-06 16:45:27
这是在 Qt QWebEngine runJavascript 函数中对我有用的唯一解决方案。谢谢
2021-03-09 16:45:27