Frames Solved : How to Design with Frames without problems

This tutorial details all procedures for ensuring that you use frames to their fullest potential, and how to get around all problems that were considered drawbacks in the past. Now you can use frames without any hesitation.

I (along with substantial help from Thierry Koblentz) appear to have solved the problems of frames, maybe forever!!

The problems with frames:
1) they open naked without their parent frames
2) a page opens in the right frameset but the other framed pages are wrong
3) the browser's history gets stuffed up/doesn't work as expected
4) pages get incorrectly bookmarked

also
5) pages or framesets get framed by other sites eg. hotmail with warning - you are opening a site outside of hotmail.
6) Opening the page you want in the frameset you want.

We have found solutions for all of the above. Thierry has a new in depth article that goes into quite a lot of detail and can be found here http://www.madcowwwebdesign.com/webmasters/Frames/default.asp

1a) Use the FrameJammer command for each framed page - this makes a page open in it's frameset if it is called naked without it's frameset.

Or

1b) Use this Javascript code along with 2a below:

<script language="JavaScript">
<!--
//This little bit of code will redirect the user to the frameset (at /home/frame.asp) and load the desired page in the 'Main' frame.
var qstring=''
if (location.search.length>1) qstring='&'+(location.search.substr(1))
if (window.name!='Main' && !((self.innerHeight == 0) && (self.innerWidth == 0)))
top.location.replace('/home/frame.asp?main='+location.pathname+qstring)
//-->
</script>

2a) Make the *frameset* an ASP (or similar) page, make the src attribute for one or each of the frames dynamic, and then pass parameter(s) to the frameset to define what pages to load.

eg. the code in your frameset for the actual frames part should look like this (note the ASP in the 'Main' frame). Obviously this page will have to be saved as an ASP page (in this example 'frame.asp')..

<frameset rows="80,*" cols="*" frameborder="NO" border="0" framespacing="0">
<frame name="Banner" scrolling="NO" noresize src="/myDirectory/Bannerpage.htm" frameborder="NO" marginwidth="0" marginheight="0" >
<frameset cols="100,*" frameborder="NO" border="0" framespacing="0">
<frame name="Contents" noresize scrolling="NO" src="/myDirectory/Contents.htm" frameborder="NO" marginheight="0" marginwidth="0" target="Main">
<frame name="Main" src="<%=Request.QueryString("main")%>" frameborder="NO" marginwidth="0" marginheight="0">
</frameset>
</frameset>

Then if you want yourpage.htm to open in a frameset, your link would look like:

frame.asp?main=PageToOpenInMainFrame.htm

You can also repeat this technique for the other frames in your frameset


2b) and 3)
alternatively to the above option for 2a (and 1b) or in addition to that option, there is another option as
follows:
Presuming one of the frames contains the 'main' part of your content, you can use the 'document.location.replace' method between frames so that the 'main' frame controls what other pages are loaded.
The advantage of this over the 'document.location.href' method is that the browser's history item for the pages you are changing *replace* the existing page, and therefore the browsers history is not disturbed, as well as the fact that as a result the navigation frames will not compose part of the browser's history, which in itself solves 3).
An example of how this works is as follows:

function document_onLoad() {
if (top.NameOfFrameToChange.document.title != "Title Of Frame Page")
// title may have spaces by the way
{
window.parent.NameOfFrameToChange.document.location.replace("FramePage.html");
}
}

The purpose of the 'if' statement is to check if the correct page is already loaded to save unnecessary reloading of pages. Then in your Body OnLoad event you would call the function. eg:
<body onLoad="return document_onLoad();">

The "NameOfFrameToChange" is the name you gave the frame when defining the frameset.
The "Title Of Frame Page" is the title attribute of the frame page that you want to be loaded in the frame (and to check that it is loaded), and CAN contain spaces.
The "FramePage.html" is the file name of the frame page that you want to be loaded in the frame.

The 2b) method and the 2a) method (which I first learned of from Thierry) will be applicable in different situations depending on your needs, but in conjunction with the other relatively simple solutions should solve all your frame problems. 1b is good because you can put it in an include javascript file and then reference that javascript file in all the pages that you want loaded in a particular frameset, and makes it easy for moving pages around as you only need to change one file.

4) You can use the "frame booker" command to put a link on your frameset pages that will enable users to correctly bookmark a page within a frameset.

5) The "frame jammer" command also stops your pages and/or framesets being 'framed' by other sites - it will break the pages out of the frames.

6) You can load pages you want in frames you want using URLs like this:

frame.asp?main=PageToOpenInMainFrame.htm

and then you can use this procedure, repeating the ASP code for each frame you want explicit control over, and using these URLs load as many pages as you want in to the right framesets (eg frame.asp?main=Page1.htm&banner=/mydirectory/Page2.htm), or alternatively, you can use 2b in specific cases where you don't want the default frame page loaded in one of the frames like in the situation where you use 2a above.

 

Additional frames info/help:

You should put the "Netscape resize fix" command on the *frameset* page so that you only have to apply it once for each frameset and don't have to put it on every page that is part of the frameset.

The commands discussed are available at the MM exchange. Search on 'jammer' and 'booker'

Murray Summers made the following comment in regards to this:
I have found that the Netscape resize fix on the frameset is not good enough. I will still get hosed framesets from time to time. What works for me is to put a refresh directly in the outermost frameset tag, like this -
<frameset blah blah onResize="if(window.netscape){history.go(0)}">

You can try out 1b, 2a & 2b (the 1b and 2b code is in a javascript include), and 5 at www.psaproject.com.au/ypp/login.asp. After navigating through a few pages around the site, if you check your browsers back button, there will be none of the banner frames in the history! An example of 6 can be seen upon navigation to the above link, as it is a direct link to a page which SHOULD be in a frameset, and since it isn't, get's loaded into a frameset.

You would think Microsoft would let everyone know of these workarounds for frames, but I didn't learn this from them!

These methods have worked for me in IE5, IE6, NS4.7, NS6.2 on Windows 98 & 2000.

If you would like a more detailed explanation of frames, visit Thierry's excellent new in depth article here http://www.madcowwwebdesign.com/webmasters/Frames/default.asp


Enjoy!

Regards
Matt

Comments

Be the first to write a comment

You must me logged in to write a comment.