[ Team LiB ] Previous Section Next Section

10.5 Passing Data Between Pages Via Frames

NN 2, IE 3

10.5.1 Problem

You want to move user-influenced data from one of your pages to another without server intervention while using a frameset.

10.5.2 Solution

The window object representing the frameset remains fixed while documents move in and out of child frames. This top window is capable of storing JavaScript data of all types in global variables. Use an onunload event handler of a framed page to preserve the data in a global variable of the frameset's window. In the following example, a string from a text input element is stored in a global variable called userName:

<script language="JavaScript" type="text/javascript" >
function saveData( ) {
    top.userName = document.forms[0].userName.value;
}
</script>
...
<body onunload="saveData( )">

In the second document, an onload event handler retrieves the data and assigns the value to a text input field on the second page:

<script language="JavaScript" type="text/javascript" >
function readData( ) {
    if (typeof top.userName != "undefined") {
        document.forms[0].userName.value = top.userName; 
    }
}
</script>
...
<body onload="readData( )">

You can embed both event handlers and functions into all related pages to keep the data moving through all page visits.

10.5.3 Discussion

Some significant benefits accrue to the frameset approach of passing data, but you should also be aware of potential downsides. One of the biggest benefits is that you can store any JavaScript data type in a variable. Conversion of objects or arrays to strings is not necessary. At the same time, the typical data-length limits that confine the amount of data transferable via cookies or URLs do not apply. You also don't have to predefine variables in the framesetting document. JavaScript automatically declares and initializes a global variable when you assign a value to a variable name as a property of a window (or frame) object.

A value assigned to a top window variable remains in effect as long as the framesetting document remains loaded in the browser. Therefore, if the site design allows users to navigate one of the frames to a destination outside of the frameset's server and domain, the value will still be there when navigation in that frame returns to the original server and domain. Scripts from outside the frameset's server and domain do not have access to the top window's variables because of blockades formed by the same-origin security policies in force in today's browsers.

Perhaps the most vulnerable aspect of using window global variables as temporary data stores is that they generally do not survive reloading of the page. If the user intentionally or accidentally clicks the Refresh or Reload button of the browser, the entire frameset reloads, causing all variable values to disappear. This is the reason the solution's readData( ) function checks for the existence of the variable in the framesetting window before accessing its value. By relying on the data to persist no longer than a change of documents in one frame, this potential problem does not loom so large.

Another consideration is not every web designer is enamored with frames, for a variety of reasons. Users probably don't care that much unless the frameset design (and navigation system within the frameset) makes Back and Forward button navigation confusing. One way to minimize this confusion while still deriving the advantage of a relatively stable framesetting window is to create a frameset consisting of two frames, one visible and the other invisible:

<frameset rows="100%, *" border="0">
    <frame name="main" src="content.html">
    <frame name="hidden" src="blank.html">
</frameset>

With this arrangement, you have two window objects to use as temporary data repositories: the top window and the hidden frame (parent.hidden). Some designers use this hidden frame scheme to let a faceless Java applet reside in the hidden frame, maintaining an open connection with the server, while the visible frame's document feeds off real-time data that arrives to the applet.

You can use this hidden frame scheme to further minimize the delicate state of variable data stored in a window object. Many (but not all) browsers preserve form control settings and values during page reloads. Therefore, instead of saving the data to window variables, save them as strings for text input or textarea elements. For example, if you are creating a shopping cart for a web site, you can accumulate ordered items in fields of a hidden frame as the user navigates the visible frame to various product pages. At checkout time, the visible shopping cart page retrieves the data from the hidden frame's form fields, and generates a nicely formatted page (perhaps using document.write( ) statements to assemble the HTML for the cart page). If you attempt this kind of persistence—especially for an e-commerce site—be sure to test the reliability of the hidden field data during reloads of the frameset on as many browsers and operating systems as possible. In your tests, include navigating out of the site via the browser's Back button, and then returning to the site via the Forward button. If the data in the hidden text boxes survives, that's a good sign.

10.5.4 See Also

Chapter 7 on managing frames and framesets.

    [ Team LiB ] Previous Section Next Section