10

我正在开发一个在网页上模拟键盘事件的 Google Chrome 扩展。

我发现由于这个 webkit 错误event.initKeyboardEvent()而无法正常工作, 并且我还找到了一些解决方法,例如SO Question

但是,在事件对象上定义属性不起作用,因为扩展的内容脚本有自己的“平行世界”,因此内容脚本中定义的属性对网页脚本不可见。

我唯一也是最后的希望 DOM 4 事件构造函数在 Google Chrome 中工作,并且可以通过构造函数正确初始化键盘事件

var event = new KeyboardEvent("keypress", {key: 'U+0041', char: 'a', ... })

不幸的是,它失败了:

TypeError: illegal constructor  

我无法在 Chrome 中找到有关支持的事件构造函数的任何文档。谁能指出我一些文档/源代码?

在 Google Chrome 扩展程序中模拟键盘事件的任何其他方式?

(注意,TextEvent 无济于事,因为许多现实世界的控件都听keydown/keyup专门听)

4

3 回答 3

11

以防有人遇到我在使用特定键码触发键时遇到的问题。这是一种方式。

首先,我在上面尝试了@RobW的答案,但没有运气。未通过任何键码,始终未定义。

然后我查看了@disya2的答案,它确实有效。

所以这里有一些代码: -

显现

"permissions": [
    "debugger"
  ],

内容脚本.js

chrome.runtime.sendMessage({ pressEnter: true });

背景.js

chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
    if(message.pressEnter){
        chrome.tabs.query({active: true}, function(tabs) {
            chrome.debugger.attach({ tabId: tabs[0].id }, "1.0");
            chrome.debugger.sendCommand({ tabId: tabs[0].id }, 'Input.dispatchKeyEvent', { type: 'keyUp', windowsVirtualKeyCode:13, nativeVirtualKeyCode : 13, macCharCode: 13  });
            chrome.debugger.sendCommand({ tabId: tabs[0].id }, 'Input.dispatchKeyEvent', { type: 'keyDown', windowsVirtualKeyCode:13, nativeVirtualKeyCode : 13, macCharCode: 13  });
            chrome.debugger.detach({ tabId: tabs[0].id });
        });
    }
});
于 2016-01-11T13:39:29.080 回答
8

因为当您从内容脚本向页面发起事件(反之亦然)时,Chrome 不会保留自定义属性,所以在页面中注入一个脚本来接管这项工作。这是一个显示这个想法的基本示例。它是可用的,尽管keykeyCode属性没有正确处理(无论如何都不应该使用)。

// Example: Say, you've got a reference to a DOM element...    
var elem = document.body;
// And you want to "type" "A"
var charCode = 65;

// Now, you want to generate a key event...
triggerKeyEvent(elem, charCode);

// triggerKeyEvent is implemented as follows:
function triggerKeyEvent(element, charCode) {
    // We cannot pass object references, so generate an unique selector
    var attribute = 'robw_' + Date.now();
    element.setAttribute(attribute, '');
    var selector = element.tagName + '[' + attribute + ']';

    var s = document.createElement('script');
    s.textContent = '(' + function(charCode, attribute, selector) {
        // Get reference to element...
        var element = document.querySelector(selector);
        element.removeAttribute(attribute);

        // Create KeyboardEvent instance
        var event = document.createEvent('KeyboardEvents');
        event.initKeyboardEvent(
            /* type         */ 'keypress',
            /* bubbles      */ true,
            /* cancelable   */ false,
            /* view         */ window,
            /* keyIdentifier*/ '',
            /* keyLocation  */ 0,
            /* ctrlKey      */ false,
            /* altKey       */ false,
            /* shiftKey     */ false,
            /* metaKey      */ false,
            /* altGraphKey  */ false
        );
        // Define custom values
        // This part requires the script to be run in the page's context
        var getterCode = {get: function() {return charCode}};
        var getterChar = {get: function() {return String.fromCharCode(charCode)}};
        Object.defineProperties(event, {
            charCode: getterCode,
            which: getterCode,
            keyCode: getterCode, // Not fully correct
            key: getterChar,     // Not fully correct
            char: getterChar
        });

        element.dispatchEvent(event);
    } + ')(' + charCode + ', "' + attribute + '", "' + selector + '")';
    (document.head||document.documentElement).appendChild(s);
    s.parentNode.removeChild(s);
    // The script should have removed the attribute already.
    // Remove the attribute in case the script fails to run.
    s.removeAttribute(attribute);
}

这是一个触发keypress字符“A”事件的简单示例。如果要触发更多相关的关键事件,不要使用triggerKeyEvent3次(因为它有轻微的开销)。相反,修改triggerKeyEvent函数,使其使用正确的参数触发所有事件( keydownkeypresskeyup/或)。input

如果您需要能够更改altKey,shiftKey等,只需修改功能即可。
底线:我展示的示例非常基本,可以根据您的需要进行调整。

阅读更多

如果您想更改实现以匹配规范,请阅读以下来源:

如果您想了解更多关于内容脚本中脚本注入的概念,请参阅:

于 2012-12-22T17:29:33.513 回答
0

我发现 chrome 调试器协议 v1.1 是从 Google Chrome 扩展程序模拟键和鼠标事件的明确答案。部分协议可通过chrome.debugger API访问。

于 2015-12-22T08:21:27.253 回答