Web Pro Source
Web Pro Source

Reputation: 181

window.close fails when clicking links within opened window

I am opening a new window with window.open(). If I do NOTHING else on this page, and click the "close window" link, the window closes. This works perfectly; however, if I navigate between pages(all under the same domain) window.close() no longer works.

Is there a way to fix this?

Here is how I am opening pages in this example...

<a href="###" target="_blank">

Here is my close link:

<a href="javascript:void(0)" onclick="window.close()">close</a>

I use 2 methods of changing pages within the opened windows.

<select onchange="if (this.value) window.location.href=this.value"> AND STANDARD <a href="####"> tag

Do I need to navigate links within this window a certain way to still maintain my window.close() ability?

Upvotes: 1

Views: 1324

Answers (1)

Andrew Chart
Andrew Chart

Reputation: 653

You should favour using window.open() to open a new window if you want to close it using window.close(). E.g.

<script>
  function newWindow() {
    window.open('foo.html', 'myWindow'); 
    return false;
  }
</script>
  
<a href="foo.html" onclick="return newWindow()">link</a>

From MDN:

The Window.close() method closes the current window, or the window on which it was called. This method can only be called on windows that were opened by a script using the Window.open() method. If the window was not opened by a script, an error similar to this one appears in the console: Scripts may not close windows that were not opened by script.

I understand the behaviour you're describing where you can close the window as long as you don't navigate. I can replicate this in Google Chrome.

I believe this is because (from the spec):

A browsing context is script-closable if it is an auxiliary browsing context that was created by a script (as opposed to by an action of the user), or if it is a top-level browsing context whose session history contains only one Document.

Your new window is considered a "top-level browsing context", not an "auxilliary browsing context". Up until the point that you navigate, the history contains one document, so can be closed using window.close(). As soon as you navigate, the history has more than one document so it's not valid to close the window.


You should also have a read about window.opener and the security risks it poses.

window.opener provides a reference to the window object that opened the current window.

Recent advice is to use rel="noopener" on all links that open in new windows. Again, this is because setting window.opener without knowing what you're doing poses a security risk. Have a read about it here:

Links to cross-origin destinations are unsafe

Browsers are now starting to treat all target="_blank" links as if rel="noopener" had been set, even if you as a developer don't set it. You can see that this is now in most major browsers.

Therefore, you could use <a href="#" target="_blank" rel="opener">link</a> (explicitly setting window.opener) and I think you'd get the behaviour you want. However, this might not be reliable across browsers, and also has security implications as described in the web.dev article.

Upvotes: 5

Related Questions