是否可以在 JavaScript 中以编程方式模拟按键事件?
是否可以以编程方式模拟按键事件?
适用于 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);
如果您可以使用 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>
您可以像这样在元素上调度键盘事件:
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'} ));
您可以做的是通过触发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] 方法来实际触发离开浏览器沙箱的键事件。所有主要的浏览器供应商都将坚持这一安全理念。
至于诸如 Adobe Flash 之类的插件——它们基于 NPAPI——并允许绕过沙箱:这些正在逐步淘汰;火狐。
详细说明:
出于安全原因,您不能也不能(正如 Pekka 已经指出的那样)。您将始终需要在两者之间进行用户交互。另外想象一下浏览器供应商被用户起诉的可能性,因为各种编程键盘事件将导致欺骗攻击。
有关替代方案和更多详细信息,请参阅此帖子。总是有基于闪存的复制和粘贴。这是一个优雅的 例子。同时,这也证明了为什么网络正在远离插件供应商。
在选择加入 CORS 策略以编程方式访问远程内容的情况下,应用了类似的安全思维。
答案是:
一般情况下,在沙盒浏览器环境中没有办法以编程方式触发输入键。
底线:我并不是说在特殊的浏览器模式和/或实现游戏最终目标的特权或类似的用户体验下,将来不可能实现。但是,在进入此类模式之前,将要求用户提供权限和风险,类似于Fullscreen API 模型。
有用:在 KeyCodes 的上下文中,此工具和键码映射将派上用场。
披露:答案基于此处的答案。
截至 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
所需元素。