Introduction to Frames

On this page I explain how to access and influence other frames.

First of all I remind you what frames are, and why you should prepare each frame by giving it a NAME. Then I explain the frame tree and finally how to walk through the frame tree.

Frames

HTML gives you the possibility to split the window of the browser into several frames. Each of these frames forms a window of its own within the content window (or within other frames).
I use frames on this site: I split up the browser window in which you've loaded this site into three frames: the logo frame above, the navigation frame on the left and the content frame on the right.

Each frame holds a separate HTML document. You can add JavaScripts to each of these pages and they will work inside that page. You can also write scripts that influence other frames or even other browser windows, for instance loading new pages into the frame, or calling a script that resides in another frame. This page explains how all this is done.

Names and targets

First of all, you should give your frames a name:

<frame src="whatever.html" name="content">

You can use this name both in HTML and in JavaScript. HTML has the TARGET attribute with which you can specify the frame in which a page should be loaded:

<a href="the_page.html" target="content">

Now if someone clicks the link, the_page.html is loaded in the frame named content. The TARGET attribute is very versatile: it searches in all open frames and windows for the frame with name content and loads the page into it.

Doing the same in JavaScript is more difficult. JavaScript also knows the names of all the frames, but naming the name only is not enough: you should also specify where in the frame tree the frame is.

The frame tree

When you create frames, you also create a frame tree. Each frame is loaded inside another frame or inside the top window, and when you use cross-frame JavaScript, you'll have to specify the path that leads to the frame you want to influence. So first of all you need to understand the frame tree. At the top of the frame tree there's always the window in which the frames are opened, JavaScript calls this frame top.

The normal frameset

On this site index.html page contains a frameset that splits up the window into three frames called logo, navi and content:

------------------------------------------------------
| logo                                               |
|----------------------------------------------------|
|         |                                          |
|         |                                          |
|         |                                          |
|  navi   |                 content                  |
|         |                                          |
|         |                                          |
|         |                                          |
------------------------------------------------------

So JavaScript's frame tree becomes:

                            top
                             |
                             |
        --------------------------------------------
        |                    |                     |
        |                    |                     |
      logo                 navi                   content

All this is simple.

Accessing frames

Each frame has a parent: this is the frame directly above it in the tree. The parent of each of my three frames is top. (And the parent of top? Confusingly, it is top.).

So to go from navi to top you do

parent

Frames may also have children. the children of top are logo, navi and content. From top, you access the children through self.childname.

self.navi

Nested framesets

Let's make it more complicated. Suppose that I load a new frameset in the content frame that divides this frames into three. The user sees this:

------------------------------------------------------
| logo                                               |
|----------------------------------------------------|
|         |              upper                       |
|         |------------------------------------------|
|         |                                          |
|  navi   |              text                        |
|         |                                          |
|         |------------------------------------------|
|         |              lower                       |
------------------------------------------------------

However, this is the JavaScript frame tree:

                            top
                             |
                             |
        --------------------------------------------
        |                    |                     |
        |                    |                     |
      logo                  navi                content
                                                   |
                                                   |
                            ----------------------------------------------
                            |                      |                     |
                            |                      |                     |
                          upper                   text                 lower

The three new frames are children of content because the frameset that defines them is in the content frame. So to JavaScript, the page really looks like this:

-------------------------------------------------------
| logo                                                |
|-----------------------------------------------------|
|         |------------------------------------------ |
|         ||             upper                      | <-- content
|         ||----------------------------------------| |
|         ||                                        | |
|  navi   ||             text                       | |
|         ||                                        | |
|         ||----------------------------------------| |
|         ||             lower                      | |
|         |------------------------------------------ |
-------------------------------------------------------

The user doesn't see content, but it's still there. You can refer to it in JavaScript or even in an HTML target attribute and it'll work fine.

Access

Of course accessing frames becomes more complicated when the frame tree grows larger. For instance, to go from lower to navi, we'd have to do

parent.parent.navi

lower's parent is content. From here, we have to move up one parent more, and then go to navi.

Going from navi to lower would require

parent.content.lower

top

If you're dealing with really complex framesets, paths like parent.parent.parent.content.subframe threaten the clarity of your scripts. Therefore JavaScript has given us one shortcut through the tree: top. Whenever you use it, you go directly to the top frame, wherever you are.

So going from lower (or, in fact, from any frame) to navi could also be done like:

top.navi

navi is a child frame of the top frame, so directly going to top and then down to navi always works.

When working with nested framesets, use top as much as you can. It'll keep your scripts simple.

Doing something

When you arrive in the correct frame, you do whatever you want to do. For instance, if you want to change the page in the upper frame from lower, do

parent.upper.location.href = 'newpage.html';

If you want to read out its title and put it in x, do

var x = parent.upper.document.title

As you see, you first walk to the correct frame, then you access normal properties like location.href or document.title and read them out or change them.

You can also call a function in another page:

parent.upper.doIt(3)

Now you call the function doIt() in the page in frame upper and give it 3 as an argument. The same as before: walk to the correct frame, do whatever you want to do.