DISCLAIMER: I hate frames, and I don't endorse using them.
There, said it.
But on several occasions, I've had to use them due to plain stubbornness on the client's side. So I've come across a reasonably trouble-free solution to this. I say 'reasonably' because small issues like 'how do I link directly to a page' comes up, and you have to do a lot of jumping through hoops to get THAT to work. Sigh.
But here goes! Start with a 3 panel frameset like so:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>«!DOCTYPE HTML PUBLIC <font color = red>"-<font color = brown>//W3C//DTD HTML <font color = blue>4.01</font> Transitional//EN"</font></font>
<font color = red>"http:<font color = brown>//www.w3.org/TR/<font color = blue>1999</font>/REC-html401-<font color = blue>19991224</font>/loose.dtd"</font>»</font>
«html»
«head»
«meta http-equiv=<font color = red>"Content-Type"</font> content=<font color = red>"text/html; charset=ISO-<font color = blue>8859</font>-<font color = blue>1</font>"</font>»
«script type=<font color = red>"text/javascript"</font> language=<font color = red>"javascript"</font>»«!--
function loadURL() {
page = document.location.search;
if (page) { top.body.location.replace('/pages/'+page.slice(<font color = blue>1</font>)); }
}
<font color = brown>// --»«/script»</font>
«/head»
«frameset border=<font color = red>"<font color = blue>0</font>"</font> framespacing=<font color = red>"<font color = blue>0</font>"</font> rows=<font color = red>"<font color = blue>57</font>,*"</font> frameborder=<font color = red>"no"</font> on-load=<font color = red>"loadURL()"</font>»
«frame name=<font color = red>"header"</font> src=<font color = red>"(your header).html"</font> scrolling=<font color = red>"no"</font> marginwidth=<font color = red>"<font color = blue>0</font>"</font> marginheight=<font color = red>"<font color = blue>0</font>"</font> frameborder=<font color = red>"no"</font> border=<font color = red>"<font color = blue>0</font>"</font> noresize»
«frameset cols=<font color = red>"<font color = blue>120</font>,*"</font> border=<font color = red>"<font color = blue>0</font>"</font> framespacing=<font color = red>"<font color = blue>0</font>"</font> frameborder=<font color = red>"no"</font>»
«frame name=<font color = red>"panel"</font> src=<font color = red>"(your left panel).html"</font> scrolling=<font color = red>"no"</font> marginwidth=<font color = red>"<font color = blue>0</font>"</font> marginheight=<font color = red>"<font color = blue>0</font>"</font> noresize»
«frame src=<font color = red>"(your content).html"</font> name=<font color = red>"body"</font> noresize»
«/frameset»
«/frameset»
«body»You need frames, blah, blah...
«/body»
«/html»</font>[/code]
Notice the Javascript - you'll need that in order to link directly to pages within the site. Also note the names of the three frames - 'header', 'panel', and 'body'.
OK, now you'll need to create all the unique header pages. Say you had 6 sections within the site. Name your headers in a way that's easy to remember ('header-01', 'header-02', etc..) and make sure that's the title of each page («title»header-01«/title»).
Do the same for all the side panels - (e.g. ('panel-01-01', 'panel-01-02', 'panel-02-01', etc...) - just make sure you can remember which panel belongs to which section.
Now, for each of the content pages, you need to add a javascript to the «head» section. It could be embedded or linked to an external file. The code is:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
var defaultLocation = <font color = red>"http:<font color = brown>//your-site/your-page.html"</font>;</font>
function checkmenu() {
if (!top.window.frames.length||!t op.window.frames['header']||!top.window.frames['left']) {
top.location.href = defaultLocation;
return false;
}
else {
if (top.panel.document.title != checkmenu.arguments[<font color = blue>1</font>] && checkmenu.arguments[<font color = blue>1</font>] != null) {top.panel.location.replace(checkmenu.arguments[<font color = blue>1</font>] + '.html');}
if (top.header.document.title != checkmenu.arguments[<font color = blue>0</font>] && checkmenu.arguments[<font color = blue>0</font>] != null) {top.header.location.replace(checkmenu.arguments[<font color = blue>0</font>] + '.html');}
return true;
}
}
</font>[/code]
The first part of the code checks to see if the frameset is loaded and the correct frame names are present. If not, it should take you to the correct html page with the frameset code.
The second part then checks to see how many values you've passed to the function - if it's one, then only check the 'header' frame, or two then check both the 'header' and the 'panel' frames.
The last thing you need to do is add the 'on-load' condition to your body tag:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>«body .... on-load=<font color = red>"checkmenu('header-<font color = blue>01</font>','panel-<font color = blue>01</font>-<font color = blue>02</font>');"</font>»</font>[/code]
Replace the two parameters with the titles of the two frames you want to sync with.
Voila! Now whenever a page loads in the content frame, it will automatically check the top and left frames to make sure they are loaded as well.
The downside to this method? Lots of hard work and - potentially - incompatibility with older browsers, and browsers which have javascript disabled.
Use this as a quick'n'dirty fix, or if you feel inclined, improve on this code and send it back to me to show how it can be done better. I'd appreciate it!
NOTE: Because of UBB's poor HTML display, I've changes the < and > to « and ». Also, you may need to change '.html' to whatever suffix is best for your server. Also, UBB wouldn't let me put 'on-load' as one word - just remove the dash.