IE中打开器关闭时的JavaScript关闭窗口

IE中打开器关闭时的JavaScript关闭窗口,javascript,internet-explorer,Javascript,Internet Explorer,对于我的web应用程序,每当父窗口关闭时,我都需要关闭子窗口。我所说的“关闭”是指浏览器窗口实际上是关闭的,而不仅仅是导航到新页面 我已经看到了“”问题,但我的问题是这个问题的延伸。该问题的答案解决了在父对象的任何卸载事件上关闭子窗口的问题。但是卸载!=关闭(海事组织);只需单击链接即可触发卸载事件 由于JS中没有“onclose”事件,我决定最好的方法是在子对象上的父对象的卸载事件setTimeout上,查看它的父对象是否仍然存在,如果不存在则关闭: var w = window.open("

对于我的web应用程序,每当父窗口关闭时,我都需要关闭子窗口。我所说的“关闭”是指浏览器窗口实际上是关闭的,而不仅仅是导航到新页面

我已经看到了“”问题,但我的问题是这个问题的延伸。该问题的答案解决了在父对象的任何卸载事件上关闭子窗口的问题。但是卸载!=关闭(海事组织);只需单击链接即可触发卸载事件

由于JS中没有“onclose”事件,我决定最好的方法是在子对象上的父对象的卸载事件setTimeout上,查看它的父对象是否仍然存在,如果不存在则关闭:

var w = window.open("", "Logger", "height=480,width=640,resizeable,scrollbars=yes");
if (w) {
  JSEvents.on(window,'unload',function(){
    if (w && !w.closed) {
      w.setTimeout(function(){
        //IE this==w.opener
        if (!w.opener || w.opener.closed) {
          w.close();
        }
      },500);
    }
  });
}
然而,我相信我已经非常明确地表明,在IE(7)中,在父窗口或子窗口的卸载事件期间,您不能使用setTimeout。在上面的示例中,setTimeout匿名函数中的this==w.opener。此测试不会产生警报:

JSEvents.on(window, 'unload', function(){
  window.setTimeout(function(){alert('HERE');},500);
});
没有设置超时的直接
警报
将产生警报

是否有一个技巧可以在父级的子级上设置setTimeout,我可以使用它

是否有其他方法可以检测父对象何时关闭


在FF中做起来容易多了,所以我专注于在IE下实现这一点。

您是否尝试过在打开的窗口中创建这样的函数:

window.closeWithParent = function() {
  if (!window.opener || window.opener.closed) {
    window.close();
  }
};
window.parentClosing = function() {
  window.setTimeout(window.closeWithParent, 500);
};
然后从父窗口:

JSEvents.on(window,'unload', function() { 
  if (w.parentClosing) w.parentClosing(); 
});

我不确定,但我认为跨窗口与窗口对象交互可能会导致您看到的问题。同样,这种方式在子窗口范围内调用setTimeout(希望如此),而不是在卸载父窗口(这将丢失任何超时)。

问题在于,从浏览器的角度来看,窗口是一个用于显示文档内容的概念。当您从该文档导航到另一个文档时,该窗口将关闭并创建一个新窗口

浏览器概念窗口由浏览器拥有的实际客户端窗口托管,并且客户端窗口可能被重新用于显示后续文档,这实际上与您的业务无关(如果您不介意这个短语的话)

浏览器如何选择显示内容,该窗口有一个关闭按钮,该按钮可能被用户点击,这是大多数浏览器认为任何主机文档需要知道的。 因此,您现在可能发明的任何绕过这一点的技巧,如果它真的有效的话,可能会在以后版本的浏览器中通过更严格的安全性来关闭


我的建议是放弃此要求。

一旦刷新或关闭窗口,浏览器会认为该窗口已关闭。因此,对于孩子来说,一旦你刷新了家长,它的开启器就消失了

因此,您无法测试窗口是否刚刚刷新,或者是否使用JavaScript引用打开了同一域上的另一个实例。(如开窗器)

但是,您可以创建对其他窗口的间接引用,并将它们保存在跨窗口的任何浏览器存储中,甚至保存在服务器存储中。让存储器反映窗口的状态将允许其他窗口观察该窗口,即使它们没有参考

你可以使用cookies等等。我有一个使用cookies的库(它是在一年前编写的,当时不支持DOM存储,我想是FF2+,IE8+)。如果你想把它作为一个例子,我可以这样做

无论如何,您可以做的是保留一段表示父窗口的数据。定期更新它,并从孩子那里轮询它

cookies示例:

// parent
setInterval(function() { setCookie('parent_alive', new Date()) }, 1000);
// child
setInterval(function() { if (readCookie('parent_alive') < new Date()-5000) window.close() }, 1000)
//父对象
setInterval(函数(){setCookie('parent_alive',new Date())},1000);
//孩子
setInterval(函数(){if(readCookie('parent_alive')
在这里,在父对象未更新cookie“parent_alive”后5秒,子对象将关闭。主要问题是,互联网连接可能会使页面在5秒钟内无法加载,此时孩子会认为页面已关闭。因此,这是一种平衡行为

请注意,如果使用会话cookie,则轮询是非常有效的,因为它们保留在内存中。然而,如果你使用持久的cookie,你可能会碰到磁盘,这会很糟糕

是否有一个技巧可以在父级的子级上设置setTimeout,我可以使用它

在IE中不能使用来自父级的代码。当IE关闭窗口时,您从窗口中的代码定义的成员将消失,对这些成员的引用(例如指向您的函数的子级超时)将悬空。根据IE的版本,可能什么也不会发生,或者可能会出现“无法从释放的脚本执行代码”错误

你可以在孩子体内做。父节点可以在子节点onunload上设置一个标志(例如w.parentunload=true),子节点上的setInterval轮询器可以检查该标志,并关闭它自己 —

if (window.parentUnloaded && (!window.opener || window.opener.closed))
这是IE病毒吗?好。。。当然,其他浏览器对卸载的脚本的反应也不同。但是没有标准来说明这里应该发生什么。即使在同一浏览器系列中,行为也会随着浏览器的更新而改变,以避免跨上下文脚本问题

有了这样的东西和事件计时问题(*),跨窗口脚本编写要比看起来更困难。通常最好避免;如果你可以把你的“弹出窗口”放在主页的div中,通常这样做会更好

(*:存在案例(**)在一个窗口中触发事件,并在另一个窗口中的JavaScript仍在运行时执行。因此窗口“a”可以调用窗口“b”上的方法,并在窗口“b”中的其他代码仍在运行时执行该方法。如果窗口“b”中的脚本是在正常的JavaScript假设是
var w = window.open("", "Logger", "height=480,width=640,resizeable,scrollbars=yes");
if (w) {
  JSEvents.on(window,'unload',function(){
    if (w && !w.closed) {
      var srpt = w.document.createElement('script');
      srpt.type = 'text/javascript';
      srpt.text = 'window.setTimeout(function(){if(!window.opener||window.opener.closed){window.close();}},250);';
      w.document.body.appendChild(srpt);
    }
  });
}
 var int = window.setInterval(function(){
   // On opener domain change, all browsers throw an error. Lets use that error to our advantage using try/catch:
   try
     {
    if(opener && typeof opener.document != 'undefined')
    {     
     // Adding this variable fixes IE8. Why? Because F U thats why.
     var openerRef = window.opener.location.host;
    }
    else{
     // Loads the survey when opener is closed
     window.location = 'exit-survey.jsp';
    }
     }
   // Loads the survey if an error throws (error throws when opener changes domain)
   catch(err)
     {
    window.location = 'exit-survey.jsp';
     }
  }, 500);
})