如何判断函数是在已关闭或重新加载的窗口中定义的

How can one tell if a function is defined in a window that has been closed or reloaded?

本文关键字:新加载 加载 定义 窗口 判断 何判断 函数      更新时间:2023-09-26

我有一个Chrome扩展程序,其中扩展选项卡订阅后台页面发出的事件。因此,后台页的事件模块包含对扩展选项卡中定义的处理程序函数的引用。

扩展选项卡可能会关闭,从而导致处理程序仍然(大部分)工作,但不再需要。重新加载扩展选项卡时也会发生类似的情况,因为这会重新初始化其window对象,从而累积对窗口中在页面加载时指定为事件处理程序的函数(新实例)的多余引用。

我正在寻找的是后台页面事件模块能够识别对已关闭或重新加载的扩展选项卡中指定的处理程序的引用,以便它可以相应地使它们过期。

我玩弄了unloadbeforeunload事件,以使扩展选项卡有机会取消注册自己的处理程序。这似乎是理论上最理想的方法。不幸的是,这两个事件都被证明是不可靠的。

查看window.closed属性。如果全局上下文是实时的,则它是false 。如果选项卡/框架不再活动,则window.closed true(其中window是窗口对象,例如 .contentWindow 的 iframe,返回值 window.open,结果为 chrome.extension.getViews()。等)

尽管如果您首先阻止代码在窗口死亡时运行,可能会更好。

只需检查整个脚本中的 reloadwin2(),可能是在某种循环中。

function reloadwin2(){
if (otherwindow.closed)
{
return false;
}
}

感谢@Rob的反馈,我想出了以下测试:

window && window.document===document

如果在处理程序中调用此表达式时计算结果为 false,则表示其选项卡已关闭(第一次测试)或自定义处理程序以来已重新加载其选项卡(第二次测试)。

处理程序可以返回此测试的结果,以向事件模块发出信号,使其在过时过期。

第二个测试之所以有效,是因为对document的非限定引用是通过闭包访问的。在定义处理程序时,它始终等于 window.document。 另一方面,window.document 总是返回当前document对象。当它们相同时,处理程序实例是上次页面加载的实例。当然,您不必为此使用documentwindow的任何对象属性(例如,您自己的全局变量)都可以。

作为记录,我的实现中的扩展选项卡也订阅了window.unload,以便它们可以在适当的时间显式注销自己的处理程序。这主要有效,但在某些边缘情况下,上述方法可作为合适的回退。