是否可以在JavaScript中以编程方式模拟按键事件?
当前回答
基于@aljgom的回答:
这对我来说很有效。而不是像aljgom建议的那样将事件分派给元素,而是将它分派给文档。
document.dispatchEvent(new KeyboardEvent("keydown", { key: "c" }));
其他回答
这里有一个真正有用的库:https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
我不知道它是从哪里来的,但它是有帮助的。它向window添加了一个.simulate()方法。你可以简单地用KeyEvent。simulate(0,13)用于模拟enter或KeyEvent。为'Q'模拟(81,81)。
我在https://github.com/ccampbell/mousetrap/tree/master/tests上买的。
截至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代替所需元素。
如果你可以使用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 " > > < /脚本
在alex2k8的基础上,这里有一个修订版,可以在jQuery支持的所有浏览器中工作(问题是缺少jQuery.event的参数。触发器,在使用内部函数时很容易忘记它)。
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
您甚至可以更进一步,让它不仅模拟事件,而且实际插入字符(如果它是一个输入元素),但是在尝试这样做时,有许多跨浏览器的问题。最好使用更精致的插件,如SendKeys。
您所能做的就是通过触发键事件以编程方式触发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上下文中,此工具和键码映射将派上用场。
披露:答案是基于这里的答案。