javascript - 以编程方式触发键盘快捷键,例如在 Gmail 中
问题描述
有没有办法以编程方式从 Javascript 触发键盘快捷键?例如,以 gmail.com 为例,按“e”将存档选定的电子邮件。
我可以编写任何类型的代码(比如在 Chrome 扩展程序中)来模拟用户在键盘上按“e”吗?
例如,我尝试在 Chrome 控制台中复制粘贴类似这样的内容:
document.body.addEventListener('keydown', function(event) {
console.log('key detected: ', event);
});
document.body.addEventListener('click', () => {
console.log('click...');
document.body.dispatchEvent(new KeyboardEvent('keydown', {
'key': 'e',
'keyCode': 69,
'which': 69,
'code': 'KeyE',
'isTrusted': true, // this has no effect
'bubbles': true,
'cancelable': true,
'view': window,
'charCode': 0,
}));
});
因此,在页面上的任何点击都会打印出该键,这看起来与在键盘上按“e”相同。但点击事件按键不会触发 Gmail 中的“存档”功能。
是不是事件不被信任,无法按照我的意愿去做?
解决方案
我找到了一个可以满足我需要的有效解决方案。它仅适用于 Chrome 扩展程序(Firefox 扩展程序和其他浏览器可能有类似的方法)。我找不到任何仅原生 JavaScript 的解决方案(我相信由于不受信任的事件,这在设计上是不可能的)。
无论如何,Chrome 扩展解决方案的工作原理如下:
// Attach debugger to the active tab (it's the only way to send
// trusted events.
chrome.debugger.attach({tabId: tab.id}, '1.2', () => {
// Create shortcut args and send to the tab.
const eventArgs = {
'modifiers': 0,
'text': 'e',
'unmodifiedText': 'e',
'key': 'e',
'code': 'KeyE',
'windowsVirtualKeyCode': 69,
'type': 'keyDown'
};
chrome.debugger.sendCommand(
{tabId: tab.id}, 'Input.dispatchKeyEvent', eventArgs,
(result) => {
if (chrome.runtime.lastError) {
console.warn('Error sending the shortcut to active tab:',
chrome.runtime.lastError);
}
chrome.debugger.detach({tabId: tab.id});
});
});
});
请注意,当用户为这些网站安装了 Chrome 应用程序时,调试器无法附加到某些非常特定的网站,例如 gmail.com 或 drive.google.com。您可能会看到如下错误:
Cannot attach to this target.
有关详细信息,请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=885025。唯一的解决方法是卸载目标站点的 Chrome 应用程序。
推荐阅读
- cadence-workflow - 如何通过 CLI 或 Java 客户端检索 cadence 工作流结果
- spring-boot - java.lang.RuntimeException:从本地使用 Spring Boot 容器 API 时连接被拒绝
- r - 将行添加到 R 中缺少的 df 并使用 dplyr 填充 NA
- php - 在 php 上使用 mysqli 耗尽内存(256kB ???)
- c - 什么是 C/C++ 中的“抛出异常”?
- angular - Highchart 没有定义角度 9
- c++ - 如何编写将被继承的通用代码?
- python-3.x - 如何使用 groupby 与数组的组合
- python - 如何区分图形中的填充颜色和边框颜色?
- javascript - 您可以在 ionic Android 和 iOS 应用程序中使用 webRTC 吗?