81

The question is pretty much all in the title.

Is it possible (and how?) to open a popup with javascript and then detect when the user closes it?

I am using jquery within the project so a jquery solution would be good. Cheers!

Pablo
  • 4,273
  • 7
  • 33
  • 34
  • define "pop-up". Are we talking some sort of on-page rendered modal box? A javascript alert? A new browser window? – DA. Jul 20 '10 at 15:54
  • 1
    A new browser window... sorry for my lack of clarity – Pablo Jul 20 '10 at 15:58

9 Answers9

112

If you have control over the contents of the pop-up, handle the window's unload event there and notify the original window via the opener property, checking first whether the opener has been closed. Note this won't always work in Opera.

window.onunload = function() {
    var win = window.opener;
    if (!win.closed) {
        win.someFunctionToCallWhenPopUpCloses();
    }
};

Since the unload event will fire whenever the user navigates away from the page in the pop-up and not just when the window is closed, you should check that the pop-up has actually closed in someFunctionToCallWhenPopUpCloses:

var popUp = window.open("popup.html", "thePopUp", "");
function someFunctionToCallWhenPopUpCloses() {
    window.setTimeout(function() {
        if (popUp.closed) {
            alert("Pop-up definitely closed");
        }
    }, 1);
}

If you don't have control over the contents of the pop-up, or if one of your target browsers does not support the unload event, you're reduced to some kind of polling solution in the main window. Adjust interval to suit.

var win = window.open("popup.html", "thePopUp", "");
var pollTimer = window.setInterval(function() {
    if (win.closed !== false) { // !== is required for compatibility with Opera
        window.clearInterval(pollTimer);
        someFunctionToCallWhenPopUpCloses();
    }
}, 200);
Lucas
  • 16,930
  • 31
  • 110
  • 182
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 3
    I recommend the polling solution instead of the `unload` event since it is compatible with more browsers (see https://opera-bugs.jottit.com/). – Jonathon Hill May 16 '12 at 16:28
  • @JonathonHill: Agreed. I alluded to the Opera problem earlier in the answer, but I should have made the point more clearly. Thanks for the edit. Btw, what's the reason for requiring `window.closed !== false` in Opera? – Tim Down May 16 '12 at 22:39
  • It is a workaround for a bug in Opera. I discovered it from https://opera-bugs.jottit.com/. – Jonathon Hill May 17 '12 at 04:36
  • @JonathonHill: Yes, I read the page. I was hoping for more detail. Don't worry, I'll look it up. – Tim Down May 17 '12 at 08:29
  • 'closed' property is not a part of DOM specification. – Shrike Jun 05 '13 at 22:32
  • @Shrike: No. I'm surprised it hasn't been standardized in HTML5 because it is implemented in all major browsers, as far as I'm aware. – Tim Down Jun 16 '13 at 15:19
  • 1
    In any case, if using the polling option, be absolutely sure not to forget the `window.clearInterval()` call. If it's not included, the original page will continue to poll... over and over and over... – codo-sapien Jun 08 '16 at 19:52
  • @TimDown: this is realy working solution (I used pollTimer). How to implement it in "for" loop? I have the list of links and I need open every link in new window (with its own js) in "for" loop and wait until this new window will be closed and then continue loop – Romowski Aug 25 '16 at 05:39
  • Found the way: jobTimerId = setTimeout(function run() {job(); jobTimerId = setTimeout(run, 100); }, 0); – Romowski Aug 25 '16 at 07:00
15

There is a very simple solution to your problem.

First make a new object which will open up a pop like this :

var winObj = window.open('http://www.google.com','google','width=800,height=600,status=0,toolbar=0');

In order to know when this popup window is closed, you just have to keep checking this with a loop like the following :

var loop = setInterval(function() {   
    if(winObj.closed) {  
        clearInterval(loop);  
        alert('closed');  
    }  
}, 1000); 

Now you can replace alert with any javascript code you want.

Have Fun! :)

Kshitij Mittal
  • 2,698
  • 3
  • 25
  • 40
  • 1
    Note that Google sets the `cross-origin-opener-policy` header, so `winObj.closed` will return `true` even if the window is not closed. – Brian May 11 '23 at 18:41
9

Try looking into the unload and beforeunload window events. Monitoring these should give you an opportunity to call back when the DOM unloads when the window is closed via something like this:

var newWin = window.open('/some/url');
newWin.onunload = function(){
  // DOM unloaded, so the window is likely closed.
}
ajm
  • 19,795
  • 3
  • 32
  • 37
  • Thanks ajm looks great. Is there anyway to get the url of a popup by any chance? – Pablo Jul 20 '10 at 15:51
  • This won't work cross browser. You need to handle the `unload` event in the pop-up. – Tim Down Jul 20 '10 at 15:53
  • Unload fires with every new request, not just when the window closes. – Josh Stodola Jul 20 '10 at 17:28
  • Yeah, YMMV with unload. Likely, you'll need a combination of unload and beforeunload to cover the IEs. @Josh - Unload should fire whenever the Document of the child window unloads from the browser independent of requests; what behavior are you seeing? – ajm Jul 21 '10 at 14:45
  • For instance, if there are hyperlinks within the popup window, clicking them will fire `unload`. – Josh Stodola Jul 21 '10 at 14:53
  • I get this event firing twice, once when the popup window opens, and once when it closes. The first time, `this` is about:blank, and the second time, `this` is the actual window object corresponding to the page. I am checking `this.url` for being undefined to work around this. – Stephen Smith Aug 31 '18 at 16:16
6

If you can use the jQuery UI Dialog, it actually has a close event.

eje211
  • 2,385
  • 3
  • 28
  • 44
  • 12
    jQuery isn't the solution to every problem :). – s4y Jul 20 '10 at 20:41
  • 11
    True, true. I should have begun my answer with the word "if" as in "If you can use the jQuery UI Dialog" and not just *assumed* it was possible. Hey! Wait a second... – eje211 Jul 20 '10 at 22:46
  • 3
    And, when it comes to JavaScript, jQuery is never really a solution to problems, but is often a huge, HUGE, **HUGE** shortcut to the solution, whatever it may be. You learn more by taking the scenic route, but, in many cases, I and most people prefer the (huge, HUGE, **HUGE** ) jQuery shortcut. – eje211 Jul 20 '10 at 22:49
3

To open a new window call:

var wnd = window.open("file.html", "youruniqueid", "width=400, height=300");

If you just want to know when that window is going to close, use onunload.

wnd.onunload = function(){
    // do something
};

If you want a confirmation from the user before the can close it, use onbeforeunload.

wnd.onbeforeunload = function(){
    return "are you sure?";
};
jAndy
  • 231,737
  • 57
  • 305
  • 359
3

We do this in one of my projects at work.

The trick is to have a JS function in your parent page that you plan to call when the popup is closed, then hook the unload event in the popup.

The window.opener property refers to the page that spawned this popup.

For example, if I wrote a function named callingPageFunction on my original page, I would call it from the popup like this:

$(window).unload(function() {
    window.opener.callingPageFunction()
});

Two notes:

  1. This should be wrapped in a ready function.
  2. I have an anonymous function because you may want other logic in there
Powerlord
  • 87,612
  • 17
  • 125
  • 175
2

I thinks best way is:

const popup = this.window.open(url.toString());
popup.addEventListener('unload', ()=> console.log('closed'))
Serginho
  • 7,291
  • 2
  • 27
  • 52
0

Yes, handle the onbeforeUnload event for the popup window and then call a function on the parent window using:

window.opener.myFunction()
TimS
  • 5,922
  • 6
  • 35
  • 55
0

This worked for me. onunload event will be triggered whenever DOM is unloaded for example if url is changed and previous page DOM is unloaded and DOM for new page is loaded.

var newWin = window.open('/some/url',"Example");
    
newWin.onunload = function(){
     if(newWin.closed){
       // DOM unloaded and Window Closed.Do what ever you want to do here
     } 
}