如何在 Chrome 中使用 Javascript 模拟按键

How to simulate keypress with Javascript in Chrome

我找到了很多关于这个主题的信息,但其中 none 似乎(不再)有用了。

我想做的是在Chrome59中模拟key(down/press/up)事件(我真的不关心其他浏览器)。模拟事件本身不是问题,但问题是我还没有找到向后兼容并包含 charCode/keyCode 值的解决方案。如果由我决定,我会更新其他应用程序的代码以检查 key/code,但不幸的是,这不由我决定。

到目前为止我尝试过的:

var evt = new KeyboardEvent(type, {code: options.charCode, key: options.keyCode, keyCode: options.keyCode, charCode: options.keyCode, which: options.which});
element.dispatchEvent(evt);

根据 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent 这应该可以工作并使用 keyCode/charCode/which 集创建一个事件,但它不起作用:

我的代码(我试过带引号和不带引号以及用字符代替数字):

new KeyboardEvent("keypress", {code: 123, key: 123, keyCode: 123, charCode: 123, which: 123});

输出:

KeyboardEvent {isTrusted: false, key: "123", code: "123", location: 0, ctrlKey: false…}
altKey:false
bubbles:false
cancelBubble:false
cancelable:false
charCode:0
code:"123"
composed:false
ctrlKey:false
currentTarget:null
defaultPrevented:false
detail:0
eventPhase:0
isComposing:false
isTrusted:false
key:"123"
keyCode:0
location:0
metaKey:false
path:Array(0)
repeat:false
returnValue:true
shiftKey:false
sourceCapabilities:null
srcElement:null
target:null
timeStamp:2469092.6000000006
type:"keypress"
view:null
which:0
__proto__:KeyboardEvent

然后我查看了规范,发现 keyCode/charCode/which 属性 不再存在,这让我相信它已从标准中删除,不应该再这样工作:https://w3c.github.io/uievents/#keyboardevent

因为这显然不起作用,我开始研究已弃用的函数 initKeyboardEvent 并尝试了这个:

var evt = document.createEvent("KeyboardEvent");
//Chrome hack
Object.defineProperty(evt, 'keyCode', {
    get : function(){
        return this.keyCodeVal;
    }
});
Object.defineProperty(evt, 'which', {
    get : function(){
        return this.keyCodeVal
    }
});
Object.defineProperty(evt, 'charCode', {
    get : function(){
        return this.charCodeVal
    }
});
//initKeyBoardEvent seems to have different parameters in chrome according to MDN KeyboardEvent(sorry, can't post more than 2 links), but that did not work either
evt.initKeyboardEvent("keypress",
    true,//bubbles
    true,//cancelable
    window,
    false,//ctrlKey,
    false,//altKey,
    false,//shiftKey,
    false,//metaKey,
    123,//keyCode,
    123//charCode
);
evt.charCodeVal = 123;
evt.keyCodeVal = 123;

所以这看起来很有希望,但是当我发送事件时,这是我可以在处理程序中看到的事件:

KeyboardEvent
altKey:false
bubbles:true
cancelBubble:false
cancelable:true
charCode:0
code:""
composed:false
ctrlKey:false
currentTarget:input#iceform:username.iceInpTxt.bookLoginTextbox
defaultPrevented:false
detail:0
eventPhase:2
isTrusted:false
key:""
keyCode:0
location:0
metaKey:true
path:Array[16]
repeat:false
returnValue:true
shiftKey:true
sourceCapabilities:null
srcElement:input#iceform:username.iceInpTxt.bookLoginTextbox
target:input#iceform:username.iceInpTxt.bookLoginTextbox
timeStamp:9932.905000000002
type:"keypress"
view:Window
which:0
__proto__:KeyboardEvent

这是我终于放弃并决定寻求帮助的时候。有什么方法可以以向后兼容的方式正确模拟这些事件吗?

请不要建议 JQUERY 或类似的东西

好的,我终于找到问题了。代码本身实际上没问题(不推荐使用 initKeyboardEvent 的代码)。

问题是,我是在 chrome 扩展的内容脚本中执行的。在这种情况下,事件的所有属性都将重置为其默认值,然后引发事件。我现在正在向包含完全相同代码的页面添加一个脚本,它工作得很好。