Section IV.2. Writing to Other Frames and Windows


IV.2. Writing to Other Frames and Windows

You can also use the document.write( ) method to send dynamically created content to another frame in a frameset or to another browser window previously opened by a script in the same page. In this case, you are not restricted to only one call to document.write( ) per page; you can open an output stream to another frame or window and keep dumping stuff into it until you close the stream with document.close( ).

All you need for this kind of content creation is a valid reference to the other frame or window. How you generate the frameset or secondary window influences this reference.

IV.2.1. Framesets and Frames

A typical frameset document defines the physical layout of how the main browser window is to be subdivided into separate panels. Framesets can, of course, be nested many levels deep, where one frame loads a document that is, itself, a frameset document. The key to writing a valid reference to a distant frame is knowing the relationship between the frame that contains the script doing the writing and the target frame.

The most common frameset structure consists of one frameset document and two to four frames defined as part of that frameset (you can have more frames if you like, but not everyone is fond of frames). Ideally, you should assign a unique identifier to the name attribute of each <frame> tag.[*] Example IV-3 is a basic frameset document that assigns a name to each of the three frames and loads an efficient local blank page into each frame. The technique used here is to invoke a function, blank( ), that exists in the frameset (parent) document. In each case, the javascript: pseudo-URL is applied to the newly created frame. From each frame's point of view, the blank( ) function is in the parent document, hence the parent.blank( ) reference. The 100-pixel wide frame down the left side of the browser window is for a navigation bar. The right portion of the window is divided into two sections. The upper section (arbitrarily called main) occupies 70 percent of the column, while the lower section (called instrux) occupies the rest of the column.

[*] While XHTML 1.0 deprecates the name attribute for the frame element, older browsers ignore the id attribute. Due to the massive volume of framed web content that uses only the name attribute, browsers will support this attribute for many years to come. In the meantime, it is perfectly acceptable to assign the same identifier to a frame element's name and id attributes. This does not confuse scripts or link and form targets on any browser, and also validates as transitional and frameset XHTML 1.0.

Example IV-3. A simple three-frame frameset with blank pages written to each frame

 <html> <head> <script language="JavaScript" type="text/javascript"> <!-- function blank( ) {     return "<html></html>"; } //--> </script> </head> <frameset cols="100,*">     <frame name="navBar" src="/books/2/570/1/html/2/javascript:parent.blank( );">     <frameset rows="70%,30%">         <frame name="main"  src="/books/2/570/1/html/2/javascript:parent.blank( );">         <frame name="instrux"  src="/books/2/570/1/html/2/javascript:parent.blank( );">     </frameset> </frameset> </html> 

Now imagine that a modified version of Example IV-2 is loaded into the main frame. The job of the script, however, is to write the dynamic content to the frame named instrux. To accomplish this, the reference to the other frame must start with the parent document (the frameset), which the two frames have in common. Example IV-4 shows the modified page that goes into the main frame and writes to the instrux frame. The two small changes that were made to the original code are highlighted.

Example IV-4. Writing dynamic content to another frame

 <html> <head> <title>Welcome Page</title> <script language="JavaScript" type="text/javascript"> // create custom page and replace current document with it function rewritePage(form) {     // accumulate HTML content for new page     var newPage = "<html>\n<head>\n<title>Page for ";     newPage += form.entry.value;     newPage += "</title>\n</head>\n<body bgcolor='cornflowerblue'>\n";     newPage += "<h1>Hello, " + form.entry.value + "!</h1>\n";     newPage += "</body>\n</html>";     // write it in one blast     parent.instrux.document.write(newPage);     // close writing stream     parent.instrux.document.close( ); } </script> <body> <h1>Welcome!</h1> <hr> <form onsubmit="return false;"> <p>Enter your name here: <input type="text" name="entry" ></p> <input type="button" value="New Custom Page" onclick="rewritePage(this.form);"> </form> </body> </html> 

If, on the other hand, you simply want to load a different document from the server into the instrux frame, you can use a scriptless HTML link and set the target attribute to the instrux frame. A script in main can also specify a document for the instrux frame as follows:

 parent.instrux.location.href = "nextPage.html"; 

IV.2.2. Secondary Windows

Legacy browser object models provide facilities for not only generating a new browser window, but also setting the new window's size and (in Version 4 browsers and later) location on the screen. You can then use references to communicate from one window to the other, although the form of those references is quite different, depending on where the script is running.

The window.open( ) method that generates a new window returns a reference to the new window object. If you plan to communicate with that window after it has been opened, you should store the reference in a global variable. This reference is the only avenue that scripts may use to access the subwindow. Example IV-5 features a script for opening a new window and writing to it. In addition, it also inserts a brief delay to allow the often sluggish Internet Explorer for Windows to finish creating the window before writing to it, and brings an already opened but hidden window to the front, if the browser supports that feature (Navigator 3 or later and IE 4 or later).

Multiple Window Cautions

Thanks to abusive behavior by advertisers over the years, web surfers are generally annoyed with any page that automatically spawns yet another browser window. Autocratic page designers are just as guilty of causing problems: they are so protective of their sites, that a link to any destination outside of the current site automatically opens in another window, whether the visitor wants it or not.

Bear in mind that smart users know that they have the choice of opening any link in a new window via the contextual menu available on a standard link (accessed by right-clicking in Windows or Ctrl-clicking on the Macintosh). Alternatively, you can add a title attribute to a link so that if the user hovers the pointer atop the link long enough, the resulting tooltip displays an appropriate advisory (e.g., "Opens whitehouse.gov in a separate window").

Also be aware that if you attempt to use scripts to open windows automatically as the main page loads or unloads, browser popup window blockers will likely prevent your script from accomplishing its task. For these and other reasons (e.g., frequent IE security blocks between windows), I recommend against designing for multiple windows unless absolutely necessary.


Example IV-5. Opening a new window and writing to it

 <html> <head> <title>A New Window</title> <script language="JavaScript" type="text/javascript"> // Global variable for subwindow reference var newWindow; // Generate and fill the new window function makeNewWindow( ) {     // make sure it isn't already opened     if (!newWindow || newWindow.closed) {         newWindow = window.open("","sub","status,height=200,width=300");         // delay writing until window exists in IE/Windows         setTimeout("writeToWindow( )", 500);     } else if (newWindow.focus) {         // window is already open and focusable, so bring it to the front         newWindow.focus( );     } } function writeToWindow( ) {     // assemble content for new window     var newContent = "<html><head><title>Sub Window</title></head>\n";     newContent += "<body>\n<h1>This is a new window.</h1>\n";     newContent += "</body>\n</html>";     // write HTML to new window document     newWindow.document.write(newContent);     newWindow.document.close( ); // close layout stream } </script> </head> <body> <form> <input type="button" value="Create New Window"  onclick="makeNewWindow( );"> </form> </body> </html> 

Example IV-5 shows that the reference to the subwindow (stored in the newWindow global variable) can be used to call document.write( ) and document.close( ) for that window. The newWindow object reference is the gateway to the subwindow.

A script in a document loaded into a subwindow can communicate back to the window or frame that spawned the new window. Every scriptable browser (except Navigator 2) automatically sets the opener property of a new window to a reference to the window or frame that created the window (recent browsers also set this property to windows launched by a and form element target attributes). Therefore, to access the value property of a form's text box (named enTRyField) located in the main browser window, you can use the following script statement in the subwindow:

 opener.document.forms[0].entryField.value 

Remember that opener refers directly to the window or frame (as a window object) that spawned the subwindow. If you need to access content in another frame in the host window's frameset, your reference must traverse the object hierarchy accordingly:

 opener.parent.otherFrameName.document.forms[0].someField.value 




Dynamic HTML. The Definitive Reference
Dynamic HTML: The Definitive Reference
ISBN: 0596527403
EAN: 2147483647
Year: 2004
Pages: 120
Authors: Danny Goodman

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net