Home Browser Differences in window.opener Behavior
Post
Cancel

Browser Differences in window.opener Behavior

Among the more persistent bugs I have been chasing recently involves a set of interrelated windows. The case in point was a parent window (A) that opened a child window (B) via JavaScript. The child window (B) was set to check whether the parent window (A) is still open before doing any operations on it. Much to my chagrin on Internet Explorer the parent window (A) was reported as open even though it has already been closed, while other browsers said it was closed. After some interesting digging, I am going to share what I found with you.

To start off, the way I was checking whether the parent window was still open is via a simple JavaScript:

if(window.opener)

My logic was that if a parent window does not exist, then there should be no "opener" object for it. For non-Microsoft browsers that logic held up, but not for Internet Explorer. It seems that in IE the "window.opener" property stays valid EVEN after the window has been closed. Why? So you can use the "window.opener.closed" property to see if the parent window has been closed!

However, much to my suprise the Mozilla documentation also includes the window.closed property with a nice example which of course doesn't work in Mozilla. Furthermore, the old Netscape documentation has this as well:

The closed property is a boolean value that specifies whether a window has been closed. When a window closes, the window object that represents it continues to exist, and its closed property is set to true.

Of course given that this is a DOM 0 property and as I mentioned before there is no formal specification for it. However, in this case both Mozilla/Netscape AND Microsoft define this object. The question is why in the world does the window object then disappear?

The answer unfortunatly is that it is a bug - namely Mozilla bug # 165418, opened over three years ago and still not fixed (why Opera never took care of this bug, I am not sure). HOWEVER, what makes it even more frustrating is that on Mozilla browsers the "window.closed" property does work for a split second after the window is closed. If you wait longer than that, then it stops working. And in case you are relying on IE - keep in mind that there is a rather nasty Microsoft bug # 241109 that returns 'false' instead of 'true' for the 'window.closed' property.

The solution for this problem is the following JavaScript snippet:

if(!window.opener || window.opener.closed)

For Mozilla/Netscape/Opera, the first part of the if statement will trigger (until they fix their bugs). For IE 6 the first part will not trigger but the second one will. Unfortunatly, for IE v5 there is no easy solution and I will leave that exercise to the readers (there is ">one suggested by Microsoft but I personally don't like that one).

In any case, I created some test cases that can be downloaded here to tests different browsers. The page loads a second child window, which loads a third window and closes the second. The third window tests prints out the "window.opener" object and the "window.opener.closed" property. The test is run a second time exactly 1 second later. Results are as follows (I will be adding more results as I get around to testing them):

window.openerwindow.opener
.closed
window.opener (1 sec later)window.opener
.closed (1 sec later)
IE 6.0 on Windows XP SP 2[object]true[object]true
Opera 8.0 on Windows XP SP 2 and Linux Fedora Core 3nullcannot accessnullcannot access
Konqueror 3.3.1 on Linux Fedora Core 3nullcannot accessnullN/A
Firefox 1.03 on Windows XP SP 2 and Linux Fedora Core 3
Mozilla Suite v1.7.7 on Linux Fedora Core 3
[object Window]truenullcannot access

(In case you are wondering why Mozilla and IE say "object" when Opera says "null", that is explained in the Mozilla bug report: "typeof(null) is "object" in ECMAScript").

This post is licensed under CC BY 4.0 by the author.