首页 > 解决方案 > 以编程方式触发键盘快捷键,例如在 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 中的“存档”功能。

是不是事件不被信任,无法按照我的意愿去做?

标签: javascriptgoogle-chrome-extension

解决方案


我找到了一个可以满足我需要的有效解决方案。它仅适用于 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 应用程序。


推荐阅读