★ wanayoo — archive 1999 http://developer.iplanet.com/viewsource/archive/goodman_frames.htmlNouvelle recherche | Portail wanayoo
 
           
 
Sun Microsystems Logo
Products and Services
 
Support and Training
 
 

Frames of References
Scripting Frames in JavaScript
Browse
 
Downloads
 
Documentation
 
Product News
 
Support
 
For Developers
 
For Sys Admins
 
 
 
 

By Danny Goodman


Send comments and questions about this article to View Source.
Click here for printer-friendly version

More Web page authoring midnight oil has burned over incorporating JavaScript into multiple-frame sites than perhaps any other scriptable feature. Scripters with only HTML experience face utterly new concepts, while experienced object-oriented programmers may know too much to quickly grasp what's going on. Even if you've started to become comfortable with JavaScript, you may find your scripts tripping over references to objects that exist in other frames. In this article, we'll look at key object model issues surrounding frames and references.

THE OBJECT MODEL

We'll be concerned here with the object model hierarchy as it extends only as deep as the document level (once you get to a document, accessing its form elements is a comparative breeze).

We're all familiar with the following portion of the Navigator object hierarchy diagram from the Netscape documentation shown in Figure 1.


   window 
     |
     +--parent, frames, self, top 
     |
     +--location 
     | 
     +--history
     |
     +--document

Figure 1. Top of Navigator object hierarchy.

I've attempted to devise another take on this diagram to help me form a better mental image of the object model loaded into the Navigator's memory when a document (or related group of documents) loads. Figure 2 shows the results of this effort.

Figure 2. Another view of the top.

The problem with this or any other generic diagram is that the map of components at any given instant varies with the makeup of a window or frameset. Contributing further confusion is that some of the object terms-- window, parent, frames, self, and top --are interchangeable from time to time. To help you understand the dynamics of the object model under varying circumstances, we'll look at three example window/frame setups and their specific object roadmaps.

ONE WINDOW

The simplest scenario is the one in which a single document loads into the Navigator window--just your basic HTML document. The top of that object hierarchy is shown in Figure 3.

Figure 3. A one-document object model.

Script statements in this document have no difficulty referring to any object, variable, or function in the same document. Everything is contained by the single window object; nothing about the frame, top, or parent object applies here. While you could use some of those object terms as part of references to the document and its objects, such nomenclature would be unnecessary and potentially confusing to anyone reading your code.

A TWO-FRAME VIEW

Three documents are usually employed to generate a two-frame setup in the Navigator window. The first document to begin loading contains the HTML code that defines the two visible frames as components of a frameset; the other two documents are loaded into their respective frames. Except for the document's title appearing in the Navigator window's titlebar and its URL appearing in the Location field, the user sees nothing at all from the framesetting document. Even so, that framesetting document remains an active part of the object model as long as its frames are visible. Figure 4 shows the object model for this setup.

Figure 4. A two-generation object model.

Here we have two generations of window objects: one parent window and two child frames. The parent is also at the top of the hierarchy: JavaScript recognizes references including top and parent as the same window object here. Each of the child frames is also a full-fledged window object.

REFERENCES BETWEEN OBJECTS

In the two-generation scenario of Figure 4, scripts can exist in a document occupying any of the three window objects. The question, then, is, "How can a script in one object access objects, functions, and variables belonging to documents in other window objects of this hierarchy?"

Bear in mind that JavaScript is not a mind reader when it comes to understanding references. While Navigator may have the picture of the entire object map in its memory, your scripts must help JavaScript locate the desired item in this geography. Imagine giving your home address over the phone to a pizza parlor for delivery. What does the order taker know about your address? If "123 Oak Lane" is already in her scope of knowledge, you need say no more. But if the street is outside that scope, you'll also have to provide the name of the town as part of the address.

As you write a script in a document, therefore, consider the scope of that document's window, and construct your references accordingly. Let's look at what this means for three possible cross-window references.

PARENT-TO-CHILD

A framesetting document knows that it has child frames below it in the object hierarchy. In other words, its scope as a parent encompasses its child frames. If you have assigned names to those frames in their tags, you can use those names as part of the references to the frames and their documents. For example:

frameName.location
frameName.document.title
frameName.document.formName.elementName.value
frameName.document.myFunc()
frameName.document.myVar

CHILD-TO-PARENT

It is not uncommon to place functions, arrays, and variable values in a framesetting document's Head section when these items are to be shared by multiple documents in one or more child frames. I've seen many an experienced object-oriented programmer, however, expect a kind of automatic message passing to occur from child back to parent. JavaScript isn't as object-oriented as that--references to objects higher up the hierarchy need to be explicit. For example, to access a parent window's items from a script in a document occupying a child frame, the reference must include the parent window:

parent.location
parent.document.title
parent.document.myFunc()
parent.document.myVar
parent.document.myObj[i].myProperty

Because a two-generation scenario equates the parent and top objects by virtue of their place in the hierarchy, you can use top in place of parent for any of these references. My recommendation, however, is to be literal by using parent whenever you refer to a window that is one generation higher in the hierarchy. As you'll see in a moment, there is the possibility (unbeknownst to you) that some other window could ultimately become the top of the hierarchy that includes your frameset--causing your reference to generate a script error.

CHILD-TO-CHILD

While the shortest distance between two points is a straight line, you can see in Figure 4 that no straight line extends between two child frames. Their only connection is through their common parent. To help JavaScript understand a reference to an item in a sister frame, the reference must include enough information for JavaScript to find the object: beginning the reference at a point in the hierarchy that has both frames in its scope. In a two-generation scenario, that point is the parent.

Such references must therefore not only begin with the parent, but must also include the frame in the reference. For example:

parent.frameName.title
parent.frameName.document.title
parent.frameName.document.formName.elementName.value
parent.frameName.document.myFunc()
parent.frameName.document.myVar

THREE GENERATIONS

One more possibility to consider is that one of the documents loaded into a child frame is, itself, a framesetting document. This results in a third-generation of frames being displayed and built into the object model. Figure 5 shows what happens to the object model in this case.

Figure 5. A three-generation object model.

A script's scope now comes into greater play when you need to access objects or functions in other frames. For instance, there can only be one top object of any hierarchy--the first document of a family loaded into Navigator. But one of its child frames is also a parent to two "grandchildren."

When creating references among frames in a complex scenario like this, remember the issue of scope. To get from one child to its sister requires that a reference include only the parent they share. Writing extensive references from the very top would be wasteful. On the other hand, for one of the top window's children to communicate with one of its nieces requires a reference starting with the object they have in common--the top window in this case.

PARENT AND TOP[OLOGY]

It's important to avoid using the top object in references when parent will suffice. You'll never know when some other Web site loads your pages into one of its frames. In that scenario, the other site's framesetting document is the top of the hierarchy. Any reference you make to top.functionName intended for your own little kingdom will fail when the page is hosted by a foreign top document. The parent-child relationships within your documents are intact, so all valid references among your parent and its children will work fine.

LOADING ORDER

While on the subject of cross-frame references, remember that a reference to an object that isn't part of the object model will cause an script error. The order of document loading into frames is never guaranteed (due to several factors, not the least of which are server, backbone, and ISP loading), so it is hazardous to script a reference to another frame in code that executes while a document loads.

The safest place to locate scripts that must run while a multiple-frame Web presence loads is in your topmost framesetting document's onLoad= event handler. This window receives the load event after windows lower in the hierarchy have received theirs. Even so, be sure to test your scripts extensively, by frequently resizing the Navigator window (which forces a reload).

IN SUM...

Before writing a reference to any object, function, or variable residing in another frame, envision the object model for the entire set of frame relationships in the currently loaded object model. Construct the reference beginning with the lowest window object that both the script and the desired element have in common. Finally, be sure that the frame you're referencing will be loaded when the script statement executes.


Danny Goodman's 24th book is Danny Goodman's JavaScript Handbook. He is well known in the Macintosh community for his writing and programming in HyperCard and AppleScript.

(12.96)


Related Reading


Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use