1

I am trying to detect the window close event that I opened using window.open() in javascript. But for some reason, it doesn't seem to work.

Here is my code:

<html>
<head>
   <script>
     var clicktest = function() {
        var newwindow = window.open("https://www.google.com",'myPopupwindow', "height=640,width=960,toolbar=no,menubar=no,scrollbars=no,location=no,status=no");
        newwindow.addEventListener("beforeunload", function (e) {
          console.log('hey');
        });
     }
   </script>
</head>
<body>
    <button onclick="clicktest()">hey</button>
</body>
</html>

I also tried using

newwindow.onbeforeunload = function () {
    console.log('hey');
}

instead of window.addeventlistener(), but both didn't work and I did try using window instead of newwindow, still, it didn't work.

Armel
  • 2,328
  • 6
  • 16
  • 28
  • Please define "_it doesn't seem to work_". – Teemu Jan 04 '19 at 07:53
  • 1
    All examples I saw about the onbeforeunload event relate to the current window. I'm not sure you can catch this event from a different window. Moreover, in your current code there is a violation of the same-origin policy: your JavaScript code tries to access a resource on a different domain (www.google.com) - opening the window works fine, but further attempts to interact with it using JS will be blocked by your browser. See this question and answer for more on that: https://stackoverflow.com/questions/25098021/securityerror-blocked-a-frame-with-origin-from-accessing-a-cross-origin-frame – JonyVol Jan 04 '19 at 07:55
  • Check this https://stackoverflow.com/questions/3888902/detect-browser-or-tab-closing – CarloM_dtb Jan 04 '19 at 08:14
  • You could listen `focus` on the current window (not on the pop-up), and check `newwindow.closed` value. That is a boolean which is `false` as long as the pop-up is open, and when closed, the value is switched to `true`. – Teemu Jan 04 '19 at 08:21
  • Your code works if the opened website has same origin. If the other website is external then you simply cannot. – Salman A Jan 04 '19 at 08:57

1 Answers1

1

For cross-origin documents, the only solution is to poll the .closed property of the popup Window object.

But that is a very ugly thing to do, so please have a second though about why you need that.

To limit the ugliness, you can power your polling using battery friendly requestAnimationFrame:

const popup = window.open('https://google.com');
waitForClose(popup, e=>console.log('closed'));

function waitForClose(win, cb) {
  function poll() {
    if(win.closed) {
      cb();
    }
    else {
      requestAnimationFrame(poll);
    }
  }
  poll();
}

As a fiddle since StackSnippet's iframes don't allow popups.

Kaiido
  • 87,051
  • 7
  • 143
  • 194
  • Listening `focus` on the main window will do the trick without "ugly polling". User has to blur the main window in order to close the pop-up, and when coming back to main window `focus` will fire. – Teemu Jan 05 '19 at 08:54
  • @Teemu not at all, if opened as a tab, you can close it while keeping focus on the main doc, and you may also never come back to the main win but still want to know the other one got closed. – Kaiido Jan 05 '19 at 08:59
  • @Teemu and then they'll at least have their own beforeunload event to fire. Look, the question asks for an event, IMM getting the notice 20 minutes after can not be called "an event", they can't listen to the ones of the outer doc, so the closest thing to an event they can have is by polling this property. – Kaiido Jan 05 '19 at 09:07