7

I have a web application that opens multiple windows. The problem that I have is that when the parent window is closed/refreshed, the child windows remain opened. I've tried using onunload and onbeforeunload but none of them catches the window close event (in Chrome and Firefox). I have an array of windows but after refresh the reference to them is lost.

Is there any other way to catch this event?

This is my code related to closing windows (running closeAll() outside unload and onbeforeunload closes all my opened 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 works only in Chrome but not in Firefox and IE (latest versions).

flaviu
  • 163
  • 1
  • 2
  • 12
  • 1
    *"I've tried using onunload and onbeforeunload but none of them catches the window close event (in Chrome and Firefox)"* `onbeforeunload` absolutely does work in Firefox and Chrome. – T.J. Crowder Oct 12 '14 at 12:13
  • The fact that "*none of them [caught] the window close event*" suggests you've got something wrong in your code, since, as T.J. Crowder points out, they do work in those named browsers; could you show us your attempts, then we might be able to help out. – David Thomas Oct 12 '14 at 12:15
  • It seems that this code works on Chrome but not in Firefox and IE. Tested the `closeAll` function outside these events and it works. I've also found multiple references here on SO that it doesn't work on Firefox and other browsers http://stackoverflow.com/questions/14645011/window-onbeforeunload-and-window-onunload-is-not-working-in-firefox-safari-o http://stackoverflow.com/questions/20773306/mozilla-firefox-not-working-with-window-onbeforeunload – flaviu Oct 12 '14 at 12:52

4 Answers4

7

use this

var popup = window.open("popup.html", "popup", "width=200,height=200");

window.onunload = function() {
    if (popup && !popup.closed) {
        popup.close();
    }
};
Harutyun Abgaryan
  • 2,013
  • 1
  • 12
  • 15
  • I have an array of windows and I call a closeAll() function, I think my code is similar with your solution but it works only in Chrome. Found this response regarding browsers other than Chrome http://stackoverflow.com/questions/14645011/window-onbeforeunload-and-window-onunload-is-not-working-in-firefox-safari-o so I don't knnow if your solution is cross-browser. – flaviu Oct 12 '14 at 12:47
3

If you open all child windows with window.open, include this javascript in all pages, then CloseAll(false); from any included page will close all child, grandchildren, great-grand... etc., and redirect the first (root) page to login.aspx, and will not interfere with any event triggers because it pases the intial handler through.

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);
3

If the goal is to close the child window when the parent is closed or refreshed, rather than actually detecting the event, you can use a setInterval to detect when the window.opener is no longer there.

            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);
            });
2

Found a proper solution (jQuery) that works in the lastest versions of Chrome, Firefox and IE.

Initially wanted to use jQuery $().unload() function (http://api.jquery.com/unload/) but it's deprecated since 1.8 (http://bugs.jquery.com/ticket/11733). Since $().unload() is the shortcut for $().bind('unload', fn), I tried to use the basic one and it worked.

$(window).on('unload', function() {
    closeAll();
});
flaviu
  • 163
  • 1
  • 2
  • 12