捕获子窗口的全局窗口对象以进行刷新



友好的互联网用户,快速场景:我有一个使用window.open('/tools', '_blank')打开的子窗口进行工具的应用程序。它返回一个window对象,我可以将事件侦听器附加到该对象,但当用户点击刷新按钮,或者窗口执行重定向时(我的窗口执行重定向,因为它有搜索功能(,window对象就会被破坏,或者至少我不能用它来获取当前窗口。所以我的应用程序认为窗口是关闭的,尽管它不是。

当我需要使用window对象在主应用程序和窗口之间交换消息时,这就成了一个问题。如果用户更改了window对象,则此操作将不再有效。我只是想知道是否有更好的方法。

显然,我可以用HTML在应用程序中内置提示,但出于清洁的原因,我试图避免这种情况,这样用户就可以使用操作系统的窗口系统来简化应用程序的使用。

就代码示例而言,没有太多要展示的,我有两个脚本,一个在主脚本上,另一个在工具窗口上

主要

$("#btn").on('change', function() {
const windowRef: Window | null = window.open('/tools', '_blank');
if (windowRef)
$(windowRef).on('load', function() {
windowRef.connect = function() {
// Initialise tools and functions here
};
$(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
});
});

工具窗口

...
<body>
<script defer>
new Promise((ok, err) => 'connect' in window ? ok(window.connect()) : err());
</script>
</body>

问题不是,到子窗口的连接被破坏,因为刷新或重定向时不会发生这种情况。您可以通过windowRef.closed进行检查。我的猜测是,您的初始化函数包含必须在刷新/重定向后重新应用的逻辑。带有以下代码:

windowRef.connect = function() {
// Initialise tools and functions here
};

您为新打开的窗口定义了一个全局函数,该函数随后在新窗口中调用。刷新/重定向页面时,javascript所做的所有临时更改都将丢失。windowRef.connect也是如此,但$(windowRef).on('load'; ...):也是如此

$("#btn").on('change', function() {
const windowRef: Window | null = window.open('/tools', '_blank');
if (windowRef)
// The registration of this listener is lost when the subwindow is refreshed
$(windowRef).on('load', function() {
windowRef.connect = function() {
// Initialise tools and functions here
};
$(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
});
});

这意味着当刷新子窗口时,子窗口中的以下脚本:

...
<body>
<script defer>
new Promise((ok, err) => 'connect' in window ? ok(window.connect()) : err());
</script>
</body>

将永远不会有函数window.connect,因为侦听器不再被调用。你可以用window.opener:解决这个初始化问题

主窗口:

let windowRef: Window | null;
$("#btn").on('change', function() {
windowRef = window.open('/tools', '_blank');
});
// has to be a global function accessible via window.initialize
function initialize() {
// Initialise tools and functions here
$(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
}

工具窗口:

// on load in the tool window will be called after redirect/refresh
$(window).on("load", () => {
if(window.opener) {
// Get main window, which opened the sub window and call initialize.
window.opener.initialize();
}
})

最新更新