The frameset

Ok, you're ready for part 1. This is where you find out how you want your frameset done. There is two options, a dynamically created frameset, or a regular frameset. A dynamically created frameset is where we use JavaScript to write the frameset to a document, thereby overriding already present HTML. This site is an example of a frameset created that way.

A regular frameset it created using HTML just like any other frames-enabled site. Both solutions has their pros & cons. I feel the dynamically created frameset is slightly more friendly to different browsers, but the regular frameset is easier to get running. This install guide will first create a regular frameset, and then show you how you can use that frameset for dynamic creation. If you already have a site with a frameset and want to incorporate the menu into it you can read the first part and skip the second.

Getting the frameset right

In this part we'll create a regular frames-enabled site, and then incorporate the menu into it. That way we'll look at how a frameset looks and then how the menu is inserted into it. It's not a difficult task to get right, but it might look slightly confusing at first.

What you first need to do is decide how your web-site should look. This example I'll be using here is the same frameset that's used on this site. It's a three-split window with a top-frame for the site heading, a left frame for the menu and a right frame for site content. Since you're already here you know what this kind of setup looks like, and therefore it's easy to see what it'll look like when you're finished.

The HTML behind this kind of frameset looks like this (this is not exactly what I use, it's slightly altered for readability and usability):

<FRAMESET ROWS="75,*">
  <FRAME SRC="heading.html" NAME="heading">
  <FRAMESET COLS="200,*">
    <FRAME SRC="menu.html" NAME="menu">
    <FRAME SRC="main.html" NAME="text">
  </FRAMESET>
</FRAMESET>

There's three frames: heading, menu and text. They all consist of regular HTML-documents with content. Now we want to use the JavaScript menu for this site, instead of the static HTML-document "menu.html". What we then need is another document which I've called "menu_empty.html", and we also need to split a frame into two frames. First, lets look at the document "menu_empty.html".

"menu_empty.html" is, as the file name says, an empty menu. Actually it's an HTML-document with no content. It's only a document heading, a body, but no content, like this:

<HTML>
<HEAD>
<TITLE>Site Menu</TITLE>
</HEAD>
<BODY>
<!-- BLANK PAGE -->
</BODY>
</HTML>

This document will be where we'll write the menu, it's written on top of what's already in the document. Since the menu is written on top of it there isn't a need for anything in it, so it's empty. You might like to give your users a link to the static menu should they not have a JavaScript-capable browser.

We also need the code, or else the menu won't work. All the code is kept in the file "code.html". As you might have noticed, if we want both "menu_empty.html" and "code.html" in our frameset there aren't enough frames. We have 4 documents (heading, menu, code & content (text)), but only three frames. Therefore we need to split one frame into two. It's the menu-frame that is split into two parts, one for the menu and one for the code. The code is kept in a frame with a size of 0 (zero) which means it'll be invisible or nearly invisible (some browsers make it invisible, some don't). Here's what our menu-frame looked like:

<FRAME SRC="menu.html" NAME="menu">

Now we split it so it becomes:

<FRAMESET ROWS="0,*">
  <FRAME SRC="code.html" NAME="code">
  <FRAME SRC="menu_empty.html" NAME="menu">
</FRAMESET>

Our whole frameset then looks like this:

<FRAMESET ROWS="75,*">
  <FRAME SRC="heading.html" NAME="heading">
  <FRAMESET COLS="200,*">
    <FRAMESET ROWS="0,*">
      <FRAME SRC="code.html" NAME="code">
      <FRAME SRC="menu_empty.html" NAME="menu">
    </FRAMESET>
    <FRAME SRC="main.html" NAME="text">
  </FRAMESET>
</FRAMESET>

That is actually all we need to do to have the frameset correct. You can use this setup if you want to. Keep in mind that you'd like to add a NOFRAMES-section for users with browsers that don't handle frames.

If you want to keep this setup you can go on to the second part, setting options. You can also read on and get to know how this frameset can be created dynamically, making the site slightly more browser-friendly (in my opinion it makes a site more accessible to different browsers).

Frameset on-the-fly

Now we'll take our already existing frameset and make sure it's created by JavaScript. This will make a JavaScript-enabled browser show the frameset, while those without JavaScript-support will get a regular HTML-document. There are caveats to this solution too, just like there's pros " cons with a regular frameset. Lets look at how the frameset is created.

First we'll have a look at what our frameset already looks like (just in case you forgot):

<FRAMESET ROWS="75,*">
  <FRAME SRC="heading.html" NAME="heading">
  <FRAMESET COLS="200,*">
    <FRAMESET ROWS="0,*">
      <FRAME SRC="code.html" NAME="code">
      <FRAME SRC="menu_empty.html" NAME="menu">
    </FRAMESET>
    <FRAME SRC="main.html" NAME="text">
  </FRAMESET>
</FRAMESET>

Ok? What we'll do is take this frameset, put lots of document.write()-things around it, and then throw it all into the heading of a regular web-page. A browser running JavaScript will then read the web-page down to where this frameset is, found out that it should use the script, write the frameset to the document, and then it'll find a frameset in the document and show it to the user. Sounds easy and straightforward in theory, right? It's not all that difficult in practice either. First we'll put JavaScript-statements around the whole frameset making it be written to the document. We use the document.write()-statement to do that. Here's how it'll look once finished:

document.write('<FRAMESET ROWS="75,*">');
document.write('  <FRAME SRC="heading.html" NAME="heading">');
document.write('  <FRAMESET COLS="200,*">');
document.write('    <FRAMESET ROWS="0,*">');
document.write('      <FRAME SRC="code.html" NAME="code">');
document.write('      <FRAME SRC="menu_empty.html" NAME="menu">');
document.write('    </FRAMESET>');
document.write('    <FRAME SRC="main.html" NAME="text">');
document.write('  </FRAMESET>');
document.write('</FRAMESET>');

document.write() is a JavaScript-statement telling the browser that what's between the single quotes should be written to the document. In other words we're telling the browser that this frameset we have here should be written to the document. The browser will then see the frameset and show it to the user (also known as "render the written frameset").

We're not finished yet, there's a couple of things I'd like to do first. One thing that's neat with JavaScript is the possibility of identifying the browser and then acting accordingly. The menu I have I've only found to work like it should with Netscape Navigator 4.x and Microsoft Internet Explorer 4.x (and 5.0). We can then identify those two browsers and make sure that only they get the JavaScript-menu, and give other users a regular HTML menu (the document we before called "menu.html". This is what I do on my site.

To make this possible we need to check what browser the user has, and then make sure we change what's written to the document. For this I use this code:

var MTMUsableBrowser = false;
// browser sniffing routine
browserName = navigator.appName;
browserVersion = parseInt(navigator.appVersion);
if(browserName == "Netscape" && browserVersion >= 3) {
  MTMUsableBrowser = (navigator.userAgent.indexOf("Opera") == -1) ? true : false;
} else if(browserName == "Microsoft Internet Explorer" && browserVersion >= 4) {
  MTMUsableBrowser = true;
}

Yeah, I know it's got rather long lines. The lines asks the user's browser if it's Netscape (Navigator) version 3 or newer, or Microsoft Internet Explorerversion 4 or newer. It also asks if the user is running Opera, a browser that has JavaScript support but isn't able to run the menu. If the user has the right browser the variable "MTMUsableBrowser" is set to true. Otherwise it'll stay false, meaning we don't have a browser that can use the menu. We then alter the code that writes the frames "code" & "menu" to the document so that they're only written when MTMUsableBrowser is true. The code for this looks like this:

if(MTMUsableBrowser) {
  document.write('    <FRAMESET ROWS="0,*">');
  document.write('      <FRAME SRC="code.html" NAME="code">');
  document.write('      <FRAME SRC="menu_empty.html" NAME="menu">');
  document.write('    </FRAMESET>');
} else {
  document.write('    <FRAME SRC="menu.html" NAME="menu">');
}

What this code does is first to check the variable MTMUsableBrowser for true/false. If it's true it writes the frameset for the code and the menu, if not it writes a single frame with the document "menu.html". This is also done on this web-site. Lastly, what we need is to put all this code into the heading of the HTML-document. So, somewhere between <HEAD> and </HEAD> you will want to put this:

<SCRIPT TYPE="text/javascript">
var MTMUsableBrowser = false;
// browser sniffing routine
browserName = navigator.appName;
browserVersion = parseInt(navigator.appVersion);
if(browserName == "Netscape" && browserVersion >= 3) {
  MTMUsableBrowser = (navigator.userAgent.indexOf("Opera") == -1) ? true : false;
} else if(browserName == "Microsoft Internet Explorer" && browserVersion >= 4) {
  MTMUsableBrowser = true;
}

document.write('<FRAMESET ROWS="75,*">');
document.write('  <FRAME SRC="heading.html" NAME="heading">');
document.write('  <FRAMESET COLS="200,*">');

if(MTMUsableBrowser) {
  document.write('    <FRAMESET ROWS="0,*">');
  document.write('      <FRAME SRC="code.html" NAME="code">');
  document.write('      <FRAME SRC="menu_empty.html" NAME="menu">');
  document.write('    </FRAMESET>');
} else {
  document.write('    <FRAME SRC="menu.html" NAME="menu">');
}

document.write('    <FRAME SRC="main.html" NAME="text">');
document.write('  </FRAMESET>');
document.write('</FRAMESET>');
</SCRIPT>

Now you'll have a frameset that is created on-the-fly. Those users who have JavaScript toggled off or don't have JavaScript support will instead get the rest of the web-page, which I believe you should give meaningful content (if you want to see what I've done turn JavaScript-support off in your browser and reload this web-page). Apart from this there's no magic to making framesets on the fly.

Now you're finished with the frameset, and you can instead go on to part 2, setting options.


Morten Wang <warnckew@online.no>
Last modified 1999-11-07 16:16