Monday, January 09, 2006
Opening New Windows, Part 2
Blog Entry #26
window.open("opened.html", "joe", config="height=300,width=300")
Joe pops up a small window, named "joe", containing two hyperlinks:
<a href="http://www.htmlgoodies.com" target="main">If you click this, you'll get <br>HTML Goodies in the main window.</a><p><hr width=60%><p>
<a href="" onclick="window.close( );">Click this to close the window.</a>
Joe seeks to use the smaller "joe" window as a 'remote control' to load the HTML Goodies home page into the larger preexisting window. However, Joe's code above does not work as advertised, at least on my computer; with either MSIE or Netscape, the first "joe" link opens http://www.htmlgoodies.com in a third, separate browser window. Why might this be?
The Problem, and Solution #1
The problem here is easy to identify. Joe claims, "Whether you knew it or not, the big window has a name, 'main'...[I]t's the default name." Nope. DevGuru's HTML anchor tag page notes that there are four "reserved names" that can serve as values for the target attribute in an <a> tag: "_blank" (which opens the link in a separate window, as noted at the outset of the previous post), "_parent", "_self", and "_top" (outside of a frames situation, these three open the link in the same window) - "main" isn't one of them. I have no idea why the target="main" attribute/value behaves like target="_blank"; I would have predicted that the browser would ignore target="main" and then load the link into the "joe" window.
More generally, a browser window object does not have a "name" (i.e., its name property does not have a value) unless you give it one. With respect to an unnamed window, consider the following script:
Up pops a blank alert box - try it yourself.
At this point, you may be thinking, "Well, why don't we name the big window 'main' with a window.name='main' command in the Primer #11 Script, and see if that works?" Ah, splendid - this does indeed set things to right! Once we've done that, "joe" smoothly loads the HTML Goodies home page into "main", although on my computer the implementation thereof is somewhat browser-dependent: with Netscape, focus remains with "joe" (it's still on top) after http://www.htmlgoodies.com has loaded, but with MSIE, focus is transferred to "main" ("joe" falls behind), which might not bother some people, but it bugged me...after a bit of experimentation, I found that putting onUnload="window.blur( );" in the <body> tag of the "main" window document allows focus to remain with "joe", regardless of browser. (Conversely, if you want focus to be transferred to the preexisting window, then you can ensure this by putting onUnload="window.focus( );" in the <body> tag of its document.)
In reciprocal fashion, the "main" window's document can use the following code to open a link in the "joe" window:
Click <a href="http://www.some_web_page.com" target="joe">here</a> to load a new page into the smaller window.
Lastly, contra Primer #11, loading a new file into the "joe" window via a link in the "joe" window document ("opened.html" in this case) does not require target="joe" in the anchor tag, which by default opens the destination page in the same window, and thus no 'targeting' is necessary.
Solution #2: the opener property
Briefly mentioned in the "Referencing a Window" section of Blog Entry #18, the window object has an opener property by which a newly opened window can reference the preexisting window that opened it. The window.opener reference can be used in all manner of relevant command statements to affect the opening window and the document it holds. For example, if the "opened.html" document of the "joe" window contains:
window.opener.location = "http://www.htmlgoodies.com";
we can load the HTML Goodies home page into the "main" window;
window.opener.document.title = "Opening New Windows";
window.opener.document.forms.elements.value = "Let's review, shall we?";
we can change Primer #11's "Click Here For What You've Learned" button into a "Let's review, shall we?" button.
You get the idea. As usual, such commands can be either placed normally in a script or assigned to a suitable event handler.
Now, if the "opened.html" document of the "joe" window were to open a third window, "burns":
window.open("opened1.html", "burns", "width=500,height=200");
then the "opened1.html" document can use window.opener commands to affect the "joe" window and "opened.html" document. Continuing "[i]n this way, you can end up with a chain of opened windows, each of which has an opener property pointing to the window that opened it," quoting Netscape. Relatedly, the "main" window does not itself have an opener window, and the use of window.opener commands in the "main" window document would throw errors.
Now then: what about referencing an opened window from the opener window? We can do that, too...
Variabilizing an 'openee' window
Using a syntax recalling that of the prompt( ) method, we can assign a window.open( ) command to a variable; this variable can then be used to reference the newly opened window:
var zork = window.open("http://www.some_web_page.com", "new_window_name", "new_window_features");
The statement above should be placed in a script; if it is assigned to an event handler, then the zork variable will not be recognized subsequently in the document source code.
It is tempting to think of zork as the name of the new window, but just to be clear, zork variabilizes/references the new window object as a whole, with all its properties, including its name property.
We can now construct zork command statements, to be placed in the opener window's document, to affect the zork window and its document:
zork.status = "Jai guru deva om";
zork.document.bgColor = "blue"; etc.
I've put together a demo that illustrates some window.opener and zork commands. We'll see more variabilized-openee-window commands in action in the Primer #12 Script.
Now that we have that all sorted out, what about that second "joe" window link, huh?
Closing a window
Complementing the open( ) method, the window object has a close( ) method, taking no parameters, that can be used to close a window, very much like selecting the Close command under the File menu. As shown above, the "joe" window assigns a window.close( ) command to an onClick event handler in an anchor tag, giving a link for closing the "joe" window; this code, taken from the "joe" source, is a bit different than the code appearing in the "Closing The Window" subsection of Primer #11, however:
<A HREF="" onClick="self.close">Click To Close</A>
Note that "close" is not followed by parentheses - mere sloppiness, one would assume - but then Joe says, "The command 'close' is a property that does the dirty work," granted that close( ) is listed as a method on the "Click Here For What You've Learned" page. (Actually, the window object does have a read-only Boolean closed property "that determines if a window has been closed," quoting DevGuru.) The use of "self" instead of "window" is OK, even as Joe strangely states that "...'self' is a property of whatever it happens to be sitting on"; as discussed in the aforelinked "Referencing a Window" section of Blog Entry #18, the "self" property of the window object is synonymous with "window" in referring to the currently active window.
Joe leaves the href attribute value blank "...so that the link points to nothing prevent[ing] another page from loading." On my computer, and when using either MSIE or Netscape, I find that the href attribute value in this case doesn't matter - for example, href can alternately be set to the current document or to any other Web page - when the link is clicked, the window.close( ) command overrides the default linking action, and the window closes. However, empty quotes are easy to type, so good enough.
If desired, the second "joe" link can be retooled to close the "main" window via assigning "window.opener.close( );" to the onClick attribute.
pop.setTimeout("self.close( )", 3000);
// The self-closing window is assigned to a pop variable.