是否可以在JavaScript中以编程方式模拟按键事件?
当前回答
让它工作的关键部分是认识到charCode, keyCode和这些都是不推荐的方法。因此,如果处理按键事件的代码使用这三个中的任何一个,那么它将收到一个伪答案(例如,默认值为0)。
只要使用非弃用的方法(如key)访问按键事件,就应该没问题。
为了完成,我添加了触发事件的基本Javascript代码:
const rightArrowKey = 39 const event = new KeyboardEvent('keydown',{'key':rightArrowKey}) document.dispatchEvent(事件)
其他回答
在某些情况下,按键事件不能提供所需的功能。从mozilla文档中我们可以看到该特性已被弃用:
不再推荐使用此特性。虽然一些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除了,可能正在被删除的过程中,或者可能只是为了兼容性的目的而保留。避免使用它,并尽可能更新现有代码;请参阅本页底部的兼容性表,以指导您的决定。请注意,此功能可能在任何时候停止工作。
因此,由于按键事件是由两个随后触发的事件keydown和接下来的同一个按键的keyup组合而成的,只需一个接一个地生成事件:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
在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。
你可以用下面的代码模拟输入密码:
铬测试100%工作
DoCustomEvent('password', '#loginpin');
function DoCustomEvent(ct, elem){
var key;
var pressEvent = document.createEvent("CustomEvent");
pressEvent.initCustomEvent("keypress", true, false);
for (var i =0; i < ct.length; ++i)
{
key = ct.charCodeAt(i);
pressEvent.bubbles = true;
pressEvent.cancelBubble = false;
pressEvent.returnValue = true;
pressEvent.key = ct.charAt(i);
pressEvent.keyCode = key;
pressEvent.which = key;
pressEvent.charCode = key;
pressEvent.shiftKey = false;
pressEvent.ctrlKey = false;
pressEvent.metaKey = false;
document.querySelector(elem).focus();
//keypress //beforeinput //input //sendkeys //select
setTimeout(function() {
var e = new window.KeyboardEvent('keypress', pressEvent);
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', pressEvent);
document.activeElement.dispatchEvent(e);
}, 0);
document.querySelector(elem).value = document.querySelector(elem).value + ct.charAt(i);
}
您所能做的就是通过触发键事件以编程方式触发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上下文中,此工具和键码映射将派上用场。
披露:答案是基于这里的答案。
截至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代替所需元素。
推荐文章
- 克隆对象没有引用javascript
- 验证字符串是否为正整数
- 如何获得一个键/值JavaScript对象的键
- 什么时候JavaScript是同步的?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?