所以,我有一个网页可以打开另一个页面(浏览器选项卡)作为第一个的孩子。父选项卡包含执行应用程序大部分工作的代码。子选项卡包含通常嵌入在父选项卡中的组件,但有时用户可能希望在自己的选项卡中打开它。所以他们可以。
问题是,子选项卡中的组件支持大约 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
);
}
这里的问题是这并没有初始化事件的所有属性,比如keyCode和which。我正在使用的键盘处理程序插件不读取keyIdentifier,它使用keyCode。我无法手动设置keyCode因为它在对象上是只读的。我想更改插件以读取keyIdentifier,但该值不是整数,它是一个 Unicode 字符串,如“U+005”等,我不想将所有 keyCodes 重新映射到插件中的那些值(尽管这可能是特定于 Chrome 的)。
因此,我还尝试实例化一个 CustomEvent,并为其添加属性,这几乎奏效了。除了 CustomEvent 有一个type属性设置为空字符串,并且不能被覆盖,所以插件不会捕获它,因为它不是“keydown”类型等。
我一直觉得我错过了一些应该使这成为可能的东西。这就是为什么我避免使用其他解决方案,例如重新映射值,或在子窗口中设置所有新的处理程序等。
感觉应该可以将键盘/鼠标事件通过管道传输到父窗口。不过,到目前为止,我似乎找不到方法。
有什么建议或解决方案吗?