Close all child windows when the parent window is closed
I have a web application that opens multiple windows. The problem is when the parent window is closed / updated, the child windows stay open. I've tried using onunload
and onbeforeunload
, but none of them catch the window close event (in Chrome and Firefox). I have an array of windows, but after updating the link to them is lost.
Is there any other way to catch this event?
This is my code related to closing windows (starting closeAll()
outside unload
and onbeforeunload
closing my entire open window, but not when the page is refreshed):
window.unload = function() {
closeAll();
}
window.onbeforeunload = function() {
closeAll();
}
var closePopup = function(popup) {
removePopup(popup);
popup.close();
};
var closeAll = function() {
for (var popup in _this.popups) {
closePopup(_this.popups[popup]);
}
}
This only works in Chrome, but not Firefox and IE (latest versions).
source to share
Found the correct solution (jQuery) that works in latest versions of Chrome, Firefox and IE.
Originally wanted to use the jQuery function $().unload()
( http://api.jquery.com/unload/ ), but it's deprecated since 1.8 ( http://bugs.jquery.com/ticket/11733 ). Since $().unload()
is a shortcut for $().bind('unload', fn)
, I tried using basic and it worked.
$(window).on('unload', function() {
closeAll();
});
source to share
If you open all child windows with window.open enable this javascript on all pages then CloseAll (false); from any included page will close all children, grandchildren, greats ... etc, and redirect the first (root) page to login.aspx and won't interfere with any event triggers, because it makes the pass-through handler easier.
function CloseAll(bTopFound)
{
if (!bTopFound && nParent != null && !nParent.closed) {
//parent window was not closed
nParent.CloseAll(false);
return;
} else {
if (nParent == null || nParent.closed)
{
top.location = '/login.aspx';
}
}
for (var i = 0; i < Windows.length; i++)
{
if (!Windows[i].closed) {
Windows[i].CloseAll(true);
}
}
nParent = null;
setTimeout(window.close, 150);
}
var Windows = [];
//override window.open to inject store child window objects
window.open = function (open) {
return function (url, name, features) {
// set name if missing here
name = name || "default_window_name";
var newWindow = open.call(window, url, name, features);
Windows.push(newWindow);
return newWindow;
};
}(window.open);
var nParent = null;
window.onload = function (load) {
return function (e) {
nParent = window.opener;
if (load != null) {
load.call(e);
}
}
}(window.onload);
window.onunload = function (unload) {
return function (e) {
//promote first branch page to parent
if (nParent != null && !nParent.closed && Windows.length > 0) {
nParent.Windows.push(Windows[0]);
Windows[0].nParent = nParent;
}
//make first child window new root
for (var i = 1; i < Windows.length; i++) {
Windows[i].nParent = Windows[0];
Windows[0].Windows.push(Windows[i]);
}
if (unload != null) {
unload.call(e);
}
}
}(window.onunload);
source to share
If the goal is to close the child window when the parent is closed or updated, rather than actually detecting the event, you can use setInterval to determine when window.opener no longer exists.
function CloseOnParentClose() {
if (typeof window.opener != 'undefined' && window.opener != null) {
if (window.opener.closed) {
window.close();
}
}
else {
window.close();
}
}
$(window).ready(function () {
setInterval(CloseOnParentClose, 1000);
});
source to share