Search code examples
javascriptjqueryevent-handlingwindow

Why does my popup window lose its event beforeunload after a reload?


I have a small application that opens a new popup. I store the window in a variable:

popup = window.open("sites/display.html", "_blank");

After that I add a beforeunload Eventlistener:

$(popup).on('beforeunload', function(){
    // Do something
});

I then later reload the window with a button:

popup.location = popup.location;

After that if I close the window the Event beforeunload isn't fired anymore. I think it has something to do with the reload because if I dont reload the page everything works fine.

How can I fix this so the event is fired everytime the window closes?

Exact code I use:

function startClock(allowRestart) {
    saveSettings(allowRestart);
    if ($("#separated-display").is(":checked")) {
        // Separated mode activated
        if (popup == undefined) {
            openPopup();
        } else {
            if (popup.closed) {
                openPopup();
            }else{
                popup.location.reload();
            }
        }
    } else {
        // Separated mode deactivated
        if (popup != null && popup.closed == false) {
            $(popup).unbind();
            popup.close();
        }
        window.location = "sites/display.html"; // Open the clock in same window
    }
}

function openPopup(){
    // Open new popup window
    popup = window.open("sites/display.html", "_blank");

    // TO-DO: Fix event not fired after 1. window reload 2. window close
    popup.addEventListener('beforeunload', function(){
        console.log("unload");
    });
}

Solution

  • As you're trying to access the same origin (with the relative path) window using window.open(), Access error shouldn't be displayed.

    popup = window.open("/sites/display.html", "_blank")
    

    popup variable would refer to the newly created window which is a thin wrapper representing a WindowProxy object, which indeed has all features of window available.

    When the page reloads everything is set to default, and the window loses its properties set before. Therefore, the unload event attached earlier is not anymore attached. This would happen for other events as well.

    Hence the problem here that the event is being attached to the popup window just once on opening the popup, which is reset on page reload. The best way to go forward would be to add the unload event in the js file which loads specifically on sites/display.html page. There, every time when sites/display.html page loads you could access the new window object and attach events in window.load / document.ready (according to your use case).

    You won't able to attach the event to pop up before or after invoking page reload as you're doing it currently as, the property would be reset if you try setting it before/after page reload as it might be executed asynchronously.

    NOTE:

    1. You should rather use the reload() function exposed by window.location instead of updating the location property. As updating the property doesn't skip browser cache.
    popup.location.reload()
    
    1. The support for window.open is unknown for most browsers, though I was able to use it on Chrome 84.