将键盘和鼠标事件从一个浏览器选项卡发送到另一个

Sending keyboard and mouse events from one browser tab to another

本文关键字:选项 浏览器 一个 另一个 鼠标 键盘 事件      更新时间:2023-09-26

所以,我有一个网页,它打开另一个页面(浏览器选项卡)作为第一个页面的子页面。父选项卡包含执行应用程序大部分工作的代码。子选项卡包含一个通常嵌入在父选项卡中的组件,但有时用户可能想在自己的选项卡中打开它。所以他们可以。

问题是,子选项卡中的组件支持大约20个不同的键盘命令和许多与鼠标相关的命令(作为与键盘命令的组合)。我试图避免将子窗口中的每个键盘命令重新映射到父窗口中的调用。现在,在父窗口中,我使用一个插件来映射和处理所有发送到正确组件API调用的键盘命令。

想要做的是将键盘和鼠标事件从子窗口管道传输回父窗口,这样这些事件的常规处理就可以正常进行。我不想在子窗口中再次为每个命令设置特定的处理程序。管道键/鼠标事件感觉更优雅,理想情况下需要更少的代码。

我尝试的第一件事是:

// CHILD WINDOW
window.document.addEventListener("keydown",  Redispatch, false);
function Redispatch(event){  
        window.opener.myRedirector.dispatchChildEvent(event);
 }

在父窗口中,它显示了以下内容:

myRedirector.dispatchChildEvent = function(event){
    var r = dispatchEvent(e);
    console.log('dispatched event from child window');
}

在这种情况下,什么也没发生。父窗口中的console.log()函数永远不会触发,通过它,control.log()行永远不会被命中。dispatchEvent(e)调用的行为就像发生了错误,但没有抛出任何东西(这是最新的Chrome)。

因此,我尝试在父级中实例化一个新事件,如下所示(从另一篇StackOverflow帖子中可以看到):

myRedirector.dispatchChildEvent = function(e){
    var event  = document.createEvent('KeyboardEvent');
    var method = typeof event.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
    event[method](
        /* type         */ e.type,
        /* bubbles      */ true,
        /* cancelable   */ false,
        /* view         */ window,
        /* keyIdentifier*/ e.keyIdentifier,
        /* keyLocation  */ e.location,
        /* ctrlKey      */ e.ctrlKey,
        /* altKey       */ e.altKey,
        /* shiftKey     */ e.shiftKey,
        /* metaKey      */ e.metaKey,
        /* altGraphKey  */ false
  );
}

这里的问题是,这并没有初始化事件的所有属性,如keyCode。我使用的键盘处理程序插件不读取keyIdentifier,它使用keyCode。我无法手动设置keyCode,因为它在对象上是只读的。我曾想过将插件更改为读取keyIdentifier,但该值不是整数,而是Unicode字符串,如"U+005"等,我不想将所有keyCodes重新映射到插件中的这些值(尽管这可能是Chrome特有的)。

因此,我还尝试实例化CustomEvent,并向其添加属性,几乎成功了。除了CustomEvent有一个类型属性,该属性被设置为空字符串,并且不能被重写,所以插件不会捕获它,因为它不是"keydown"类型,等等。

我一直觉得我错过了一些应该让这一切成为可能的东西。这就是为什么我避免了其他解决方案,比如重新映射值,或者在子窗口中设置所有新的处理程序,等等。

感觉应该可以将键盘/鼠标事件管道传输到父窗口。不过,到目前为止,我似乎找不到办法。

有什么建议或解决方案吗?

所以,我使用的是document.createEvent(),它生成了一个已经添加了太多属性(只读)的事件对象。所以当我这样做的时候:

var event = new Event(childEvent.type);

这创建了一个正确类型的事件,但没有keyCode或keyIdentifier或其他类似的属性,我可以从childEvent动态添加它们。然后,派遣他们工作得很好。