1

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

问题是,子选项卡中的组件支持大约 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()函数永远不会触发,并且单步执行它,console.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
  );
}

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

因此,我还尝试实例化一个 CustomEvent,并为其添加属性,这几乎奏效了。除了 CustomEvent 有一个type属性设置为空字符串,并且不能被覆盖,所以插件不会捕获它,因为它不是“keydown”类型等。

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

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

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

4

1 回答 1

1

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

var event = new Event(childEvent.type);

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

于 2015-02-26T18:59:48.340 回答