Chapter 9. Frames and Addressing Frames in Windows

CONTENTS

CONTENTS>>

  •  The Window as a Complex Object
  •  Scripts That Write Scripts
  •  Summary

The Window as a Complex Object

Chapter 7, "Objects and Object Hierarchies," covered most of the key properties and methods in the window object. As you saw in the discussion of the HTML hierarchy, at the very top is the window object. However, collected with the window object are other objects, including frames, top, parent, and self.

This chapter examines using and controlling frames within the window object. JavaScript not only can direct commands to other frames within a given window, but it also can pass data back and forth between frames. You can even dynamically create a page within a frame using JavaScript.

The Frame Elements and Attributes

The first order of business is to review the HTML elements and related attributes of a frame. Keeping in mind that, for JavaScript, an element is referenced as an object and each of the element's attributes is referenced as a property, the HTML structure is a blueprint for JavaScript behaviors. Table 9.1 shows the main frame elements and their attributes.

Table 9.1. Frame Elements and Their Attributes

Frame

Frameset

Iframe

Noframe

srcrows

src

 

name

cols

name

 

marginwidth

onload

marginwidth

 

marginheight

onunload

marginheight

 

scrolling

 

scrolling

 

noresize

 

align

 

frameborder

 

height

 
 

width

   

Of all of the HTML frame elements, the key one is the frame object itself. Like images and forms, all window objects have a frames[] array. The array is a property of window and is referenced with the window's parent property. Thus, you may reference the third frame in a window as follows:

parent.frames[2] 

If a frame is within another frame, that frame's parent is the frame it is within. If you want to address the top-level window and a frame within that window, you need to address the top object in the window object like this:

top.frames[1] 

To address a subframe, you can reference the parent frame by its array element value and the subframe in the same manner. For example, if you have a frame within the fourth frame of the top level, you could address the target frame as follows:

frame[3].frame[4] 

However, you can reference frames by their names. Note in Table 9.1 that one of the frame attributes is name. Just as with forms whose properties can be addressed by names, so can frames. To see how this works and some other addressing tricks, the following frameset and pages will be used to demonstrate how you might go about creating scripts that reference different frames using JavaScript.

Setting Up the Frameset

The frameset is important in naming your frames because those names become a reference for JavaScript. This line in the script:

<frame name="header" src="head.html" border=0> 

creates an object that is referenced in JavaScript as follows:

parent.header 

Also note the order of the frames. The first frame is named header, but it also can be referenced as this:

parent.frames[0] 

Likewise, the other two frames (shown in the next frameNameSet.html listing) can be referenced by their array element number.

frameNameSet.html
<html>  <head>  <Title>Head Set</title>  </head>  <frameset rows="20%,*" frameborder=0 framespacing=0 border=0>  <frame name="header" src="head.html" border=0>  <frameset cols="20%,*" frameborder=0 framespacing=0 border=0>  <frame name="menu" src="menu.html" border=0>  <frame name="data" src="info.html" border=0>  </frameset>  </frameset>  </html>
The Header Frame

The first frame loads a page containing very simple yet important information about sending data to another frame. Because each frame has its own HTML page, the effect is passing data from one page to another. This JavaScript line addresses parent.data; the rest is document information:

parent.data.document.forms[0].elements[0].value="Greetings";

What is unique up to this point is the capability of the script to put data into another page. Data from one page in a frameset can be passed to or read from another page within the same set.

head.html
<html>  <head>  <style type="text/css">  body {font-family: verdana}  </style>  <Title>Header</title>  <script language="JavaScript">  function message() {       parent.data.document.forms[0].elements[0].value="Greetings";        }  </script>  </head>  <body bgColor=#ee9caa>  <h3> Header</h3>  <form>  <input type=text>  <input type=button value="Redecorate" onclick="message()" >  </form>  </body>  </html>
The Menu Page

The page in the menu frame uses a function to pass data to the other two pages in the frameset. Not only does it pass a greeting to the data frame, but it also changes the contents (values) of the button object in the header frame. Basically, it is no different from the page in the header frame, other than that it sends data to two different pages at once.

menu.html
<html>  <head>  <style type="text/css">  body {font-family: verdana}  </style>  <Title>Le Menu</title>  <script language="JavaScript">  function changeThem() {       parent.data.document.forms[0].elements[2].value="Hi from Menu";        parent.header.document.forms[0].elements[1].value="Hello";  }  </script>  </head>  <body bgColor=#ef001b>  <h3>Menu</h3>  <form>  <input type=button value="Send Two!" onClick="changeThem()">  </form>  </body>  </html>
The Data Frame

The last frame has a couple of interesting actions. First, it gets data from the header frame by defining a variable as the name of frame[0], which we know to be header with this statement:

hi=parent.frames[0].name; 

Next, it sends a greeting in a string object that addresses the header frame by name. Figure 9.1 shows how this loud (all-caps) greeting looks. Finally, the script extracts the name from frames[1] and puts the name in one of its own form elements.

Figure 9.1. Data from properties in one frame can be passed to properties in other frames.

graphics/09fig01.gif

info.html
<html>  <head>  <style type="text/css">  body {font-family: verdana}  </style>  <Title>Info page</title>  <script language="JavaScript">  function reply() {       var hi=new String();        hi=parent.frames[0].name;        parent.header.document.forms[0].elements[0].value="Hello, " +        hi.toUpperCase() + "!";        var menName=parent.frames[1].name;        document.forms[0].elements[1].value=menName;        }  </script>  </head>  <body bgColor=#828793>  <h3>Data</h3>  <form> <h4>  <input type=text>One<br>  <input type=text>Two<br>  <input type=text>Three<p>  <input type=button value="Change Something" onClick="reply()" >  </form>  </body>  </html>

Scripts That Write Scripts

Up to this point, you have seen how to make changes by sending variables to different frames in a frameset. By passing variables between frames, you can basically establish communication between more than a single HTML page within a frameset. That is an important part of JavaScript, but what if you could dynamically alter an entire page? You could change everything from the text that appears on the screen to the entire layout of the page. This section shows how to do that.

Writing Elsewhere

Throughout the book, you have seen examples of using document.write() to place formatted text on a page. You can use the same method to write tags to create an entire page by addressing a document other than the one that you are using to write the JavaScript. Using the window.open() method, you can open a new window or target an existing one other than the one that you are using to write your script. The open() method has four arguments:

window.open(url,name,features,replace) 

Up to this point, the only argument used is url. The name argument can be used to specify a name for a new window or a target window within a frameset. By using this format, you can target a frame to be the recipient of the output generated by using document.write():

window.open("","frameName") 

From the source page within a frameset, you create a function that targets a page in another frame using this general format:

function dynamic() {       var varName = window.open("","frameName")        varName.document.write('<tags and attributes>');        varName.document.write(external variables);                 varName.document.close();  } 

Essentially, what this method accomplishes is to write a tag-based HTML page using document.write() to write the page. The function is launched from the page with the JavaScript. It opens another page, loads it with the tag-based script generated in the document.write() statements, and then closes the page. (Don't ever forget to close the page that you have opened!) Your last line in the function should always be document.close().

A Basic Dynamic Page

To see how to use the dynamic page-creation capabilities of JavaScript, the following is a simple frameset and two pages that do two things:

  • Change the background color of a page

  • Print a message on the page

The fact that the changes are being made to a different frame and that the changes are dynamic makes this interesting, not the fairly pedestrian work of changing a background color or displaying a message using document.write().

First, the frameset is unremarkable, but do note the names that have been given to the two frames. These names will be referenced in subsequent pages.

dynamicSet.html
<html>  <head>  <title> Dynamic Page Change </title>  </head>  <frameset cols="*,*" border=0 frameborder=0>  <frame name="message" src="message.html" border=0 frameborder=0>  <frame name="show" src="show.html" border=0 frameborder=0>  </frameset>  </html>

The core to this set of scripts is message.html. This page contains the JavaScript that will make the dynamic changes in the frame named show as defined in the frameset page. The main function first opens the window frame named show. (Actually, it would be more accurate to say that it targets the frame by name.) Next, it derives data from the current page and places the data into a variable named message. Then it starts using the document.write method to create a page beginning with the <body> tag. When it is finished writing the code for the page, the window is closed and the function terminates.

message.html
<html>  <head>  <title>Dynamic Change</title>  <script language="JavaScript">  function dynamic(){       var dyn=window.open("","show")        var message=parent.frames[0].document.forms[0].pass.value;        dyn.document.write('<body bgcolor=#dddddd>');        dyn.document.write('<center>');        dyn.document.write('<p><p>');        dyn.document.write('<h1>');        dyn.document.write(message);        dyn.document.write('</h1>');        dyn.document.write('</center>');        dyn.document.write('</body>');        dyn.document.close();        }  </script>  </head>  <body >  <p><p>  <h3>Enter your message in the text window:</h3>  <form>  <input name="pass" type="text"><p>  <input type=button value="Change the Page"onclick="dynamic()">  </form>  </body>  </html>

The final page, show.html, is really a dummy page for the purposes of this exercise. All it does is show that a text message and a distinct background color (hot pink!) currently appear on the page. Both the message and the background color get changed.

show.html
<html>  <body bgcolor="hotpink">  <center>  <p><p>  <h1>  Show  </h1>  </body>  </html>

Figure 9.2 shows the original frameset and pages as they appear when first loaded. Figure 9.3 shows what dynamic changes were made by the JavaScript in the page in the left frame.

Figure 9.2. The initial frameset shows two columns with a message indicating the name of the frame and page.

graphics/09fig02.gif

Figure 9.3. The script from the page in the frame on the left dynamically changes the frame on the right.

graphics/09fig03.gif

More Dynamic Frames

The initial example of using dynamic frames shows only two changes made in the page, and it has little practical use. This next example is far more elaborate and provides a practical tool for comparing font color combinations. It uses a Cascading Style Sheet for the entire frameset, and then it uses document.write in combination with the <FONT> tag to change the colors in the fonts themselves. Another frame provides both the name and hexadecimal values for trying out different color combinations. An external CSS page provides all of the pages in the frameset with a consistent color and style.

color.css
body { background-color: #decea1;  font-family: verdana  }  .header { font-size:18pt;  font-weight: bold;  color: red  }  .explain { font-weight: bold;  font-size: 11;  color: #be881d;  }  .label { font-size: 14pt;  color: #7a8215  }  .bdtext { font-size: 10;  color: #7a8215  }

The frameset has two columns and two rows in the second column. The first frame (frame[0]) uses 60% of the page for an entry display where the user can put in her color selections. The second frame (frame[1]), in the top row of the second column, shows several available names and their accompanying hexadecimal values. In the bottom-right corner is the frame named colorfont (frame[2]) that will be the target frame for the changes being devised in the first frame.

changeColorSet.html
<html>  <head>  <title> Frameset Create Page </title>  </head>  <frameset cols="60%,40%" border=0 frameborder=0>  <frame src="entry.html" border=0 frameborder=0>  <frameset rows="85%,15%" border=0 frameborder=0>  <frame src="colorname.html" border=0 frameborder=0>  <frame src="bottom.html" name="colorfont" border=0 frameborder=0>  </frameset>  </frameset>  </html>

The entry.html page has all of the code to write to the colorfont frame. Two different variables, fcolor1 and fcolor2, store the HTML color name or hexadecimal value for the colors selected. These color values are passed to the font colors in the lines typified by the following:

doc.document.write('<font size= +3 color="'+ fcolor1 +'">'); 

The font color is specified by concatenating the variable name with the rest of the tag. The result on an HTML page for the previous line, with blue as the value of the variable fcolor1, would be the following tag:

<font size= +3 color="blue"> 

The trick is to get the double quotes around the color value or name. To get the double quotes around the color, the double quotes were placed within a set of single quotes.

entry.html
<html>  <head>  <link rel=stylesheet href="color.css">  <title>Dynamic Change</title>  <script language="JavaScript">  function showcolor(){       var doc=open("","colorfont")        var fcolor1=parent.frames[0].document.forms[0].elements[0].value;        var fcolor2=parent.frames[0].document.forms[0].elements[1].value;        doc.document.write('<body bgcolor=#dddddd>');        doc.document.write('<center>');        doc.document.write('<h3>');        doc.document.write('<font size= +3 color="'+ fcolor1 +'">');        doc.document.write("J");        doc.document.write('</font>');        doc.document.write('<font color="'+ fcolor2 + '">');        doc.document.write("ava");        doc.document.write('</font>');        doc.document.write('<font size= +3 color="'+ fcolor1 +'">');        doc.document.write("S");        doc.document.write('</font>');        doc.document.write('<font color="'+ fcolor2 +'">');        doc.document.write("cript </h3>");        doc.document.write('</font> <p>');        doc.document.write('</center>');        doc.document.write('</body>');        doc.document.close();        }  </script>  </head>  <body >  <center>  <form>  <p class="header">Interactive Font Color Changer</p>  <div class="label">Text Color 1&nbsp;&nbsp;<input type="text"size="15"name="name">  <br>  Text Color 2&nbsp;&nbsp;<input type="text"size="15"name="name"></div>  <p>  <input type=button value="Color Fonts"onclick="showcolor()">  </form>  </center>  </body>  </html>

The next section of the script contains the names and the values of a sample set of HTML colors. The colors or the hexadecimal values can be copied and pasted from the color name frame to the text window in the browser to save time. The gray background was used to provide a neutral backdrop for the different color combinations.

colorname.html
<html>  <head>  <link rel=stylesheet href="color.css">  <title> color names </title>  </head>  <body>  <p class="explain">The following are several HTML colors you might want to use. Use  graphics/ccc.gifeither the names or the hexadecimal values. If you use hexadecimal, be sure to put the  graphics/ccc.gifpound sign (#) in front of the value (e.g., #2f4f4f.)</p>  <div class="bdtext">  white rgb=#ffffff  <br> red rgb=#ff0000  <br> green rgb=#00ff00  <br> blue rgb=#0000ff  <br> magenta rgb=#ff00ff  <br> cyan rgb=#00ffff  <br> yellow rgb=#ffff00  <br> black rgb=#000000  <br> aquamarine rgb=#70db93  <br> beige rgb=#f5f5dc  <br> bisque rgb=#ffe4c4  <br> blanchedalmond rgb = #ffebcd  <br> blueviolet rgb=#9f5f9f  <br> brass rgb=#b5a642  <br> brightgold rgb=#d9d919  <br> brown rgb=#a62a2a  <br> bronze rgb=#8c7853  <br> cadetblue rgb=#5f9f9f  <br> coral rgb=#ff7f50  <br> cornflowerblue rgb=#42426f  <br> darkgreen rgb=#2f4f2f  <br> darkorchid rgb=#9932cd  <br> darkpurple rgb=#871f78  <br> darkslateblue rgb=#7b68ee  <br> darkslategrey rgb=#2f4f4f  <br> darkseagreen rgb=#8fbc8f  <br> darktan rgb=#97694f  <br> darkolivegreen rgb=#556b2f  <br> darkorange rgb=#ff8c00  <br> blueviolet rgb=#9f5f9f  <br> darkturquoise rgb=#00ced1  <br> darkcyan rgb=#008b8b  <br> deepskyblue =#0bfff  <br> dimgrey rgb=#545454  <br> dustyrose rgb=#856363  <br> feldspar rgb=#d19275  <br> firebrick rgb=#8e2323  <br> forestgreen rgb=#228b22  <br> gold rgb=#cd7f32  <br> goldenrod rgb=#dbdb70  <br> grey rgb=#c0c0c0  <br> greenyellow rgb=#adff2f  <br> honeydew rgb=#f0fff0  <br> hotpink rgb=#ff69b4  <br> ivory rgb=#fffff0  <br> indianred rgb=#4e2f2f  <br> khaki rgb=#9f9f5f  <br> lightskyblue rgb=#87cefa  <br> lightgrey rgb=#a8a8a8  <br> lightsteelblue rgb=#8f8fbd  <br> limegreen rgb=#32cd32  <br> maroon rgb=#8e236b  <br> mediumaquamarine rgb=#32cd99  <br> mediumblue rgb=#3232cd  <br> mediumforestgreen rgb=#6b8e23  <br> mediumgoldenrod rgb=#eaeaae  <br> mediumorchid rgb=#9370db  <br> mediumseagreen rgb=#426f42  <br> mediumslateblue rgb=#7f00ff  <br> mediumspringgreen rgb=#7fff00  <br> mediumturquoise rgb=#70dbdb  <br> mediumvioletred rgb=#db7093  <br> midnightblue rgb=#191970  <br> navyblue rgb=#23238e  <br> orange rgb=#ff7f00  <br> orangered rgb=#ff2400  <br> orchid rgb=#db70db  <br> palegreen rgb=#8fbc8f  <br> pink rgb=#bc8f8f  <br> plum rgb=#eaadea  <br> salmon rgb=#6f4242  <br> scarlet rgb=#8c1717  <br> seagreen rgb=#2e8b57  <br> sienna rgb=#8e6b23  <br> silver rgb=#e6e8fa  <br> skyblue rgb=#3299cc  <br> slateblue rgb=#007fff  <br> springgreen rgb=#00ff7f  <br> steelblue rgb=#236b8e  <br> tan rgb=#db9370  <br> thistle rgb=#d8bfd8  <br> turquoise rgb=#adeaea  <br> violet rgb=#4f2f4f  <br> violetred rgb=#cc3299  <br> wheat rgb=#d8d8bf  <br> yellowgreen rgb=#99cc32  </div>  </body>  </html>

Finally, the dummy page simply awaits its fate to be changed. However, while it's waiting, it is dressed up in the same CSS as the other pages. Figure 9.4 shows what the viewer sees when all of these parts come together in the browser.

Figure 9.4. A designer can try out different color combinations without leaving the page.

graphics/09fig04.gif

bottom.html
<html>  <head>  <link rel=stylesheet href="color.css">  </head>  <body>  </body>  </html>
Writing to Different Windows

In addition to writing to frames in a frameset, with JavaScript, you can also write to a different window. In Chapter 7, you saw how to open a separate window. In an almost identical manner that you can write to different frames using JavaScript, you can write to different windows.

The following script opens a window with a unique name, ralph, but without a URL. In other words, it's a new window, but not with a page to go with it. One new trick is introduced, but it's essentially the same kind of script and logic as you saw using the frameset. This line establishes the window, its name, and its dimensions:

var winR=open("","ralph", "scrollbars=0, width=200, height=100, resizable=no") 

The next line creates a shortcut when writing this script:

var s=winR.document; 

Instead of having to type

winR.document.write(); 

you can now just type a much shorter version for each line because the rest of the object is contained in s:

s.write(); 

The only downside to this shortcut is that it is not quite as clear as writing out winR.document.write(). Besides, the best shortcut in JavaScript when you have a lot of repeated code that you cannot put into a loop is using cut and paste in your text editor.

winright.html
<html>  <head>  <title>Change Different Window</title>  <script language="JavaScript">  function fixWin(){       var winR=open("","ralph", "scrollbars=0, width=200, height=100, resizable=no")        var s=winR.document;        var message=document.forms[0].george.value;        s.write('<body bgcolor="hotpink">');        s.write('<h4>');        s.write(message);        s.write('</h4>');        s.write('</body>');        s.close();        }  </script>  </head>  <body >  <form>  <h3>Open and Write to a new window</h3>  <input type="text" size=30 name="george">  <p>  <input type=button value="Write to new window" onclick="fixWin()">  </form>  </body>  </html>

Figure 9.5 shows that the message in the text window has been transferred to another window created with the script in the page. The default position of a new window is the upper-left corner of the window. The little window was dragged to the middle of the larger window but, with a bit more code, you could place it where you want on the screen.

Figure 9.5. JavaScript can write to other windows as well as other frames within a frameset.

graphics/09fig05.gif

Summary

The capability to pass data between different windows and frames means that data generated in one part of a web site can be used in another part. In applications in which data entered in one page is required in another page, JavaScript can be used as the agent of communication. While you will see in Part III, "JavaScript and Other Applications and Languages," that JavaScript in combination with various server-side scripts can do a great deal more in moving data over the web, JavaScript on its own can do a great deal as well.

One of the most interesting challenges for a web designer lies in dynamically creating pages, especially ones using data passed from the originating source. While it might seem a lot easier just to pass data between text or text area windows, you have no control over formatting the materials being passed. By dynamically changing pages, you can pass data and design the page while you're doing so.

CONTENTS


JavaScript Design
JavaScript Design
ISBN: 0735711674
EAN: 2147483647
Year: 2001
Pages: 25

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