Going Dynamic
In this section, I demonstrate a few interesting concepts involving different scripting techniques.
IMO, this is the most important part of this tutorial; because a Dynamic frameset can be a solution to many problems:
- Reloading/Refreshing,
- Bookmarking,
- Avoiding "naked" frames [frames showing outside of their frameset].
A "static" frameset is a document that holds frames with default attributes values [ie. each frame hosts a default document].
A "Dynamic" frameset includes variable(s) as part of its code structure. This or these variables are used "on the fly"to Dynamically build the frameset code that is then executed by the browser.
Before "going Dynamic" we need to know what's involved:
- the code to construct the Dynamic
framesetitself, - the script(s) to pass the variable(s) to the Dynamic
frameset.
We will go through 2 solutions [client-side and server-side] to generate the frameset code then I'll show you a few ways to take advantage of the Dynamic part.
I've kept my Dynamic frameset codes very basic but it is possible to set up many more variables.
CLIENT-SIDE
Building a Dynamic frameset using JavaScript:
<html>
<head>
<title>Going Dynamic!</title>
</head>
<script type="text/JavaScript">
// Copyright 2003, Thierry Koblentz (TJKDesign.com)
// we keep only part of the URL string [at the right hand side of the question mark]
var myPage = document.location.search.substr(1);
// if we find something after the "?" we use it, if not we set the variable to "red.asp"
if (myPage.length > 0) {}else{myPage = "red.asp"}
// we start writing the frameset
document.write(
'<frameset rows="240,*,270">'+
'<frame name="top" target="main" src="green.asp">'+
'<frame name="main" src="'
// this is where we plug the variable - it will be the src value for the main frame
+ myPage +
'">'+
'<frame name="footer" src="yellow.asp" target="main">'+
'<noframes>'+
'<body>'+
'The usual...'+
'</body>'+
'</noframes>'+
'</frameset>')
</script>
</html>
SERVER-SIDE [ASP]
The file needs to be saved with an .asp extension [the server-side code is highlighted].
Building a Dynamic frameset using ASP/VBScript:
<%@LANGUAGE="VBSCRIPT"%>
' Copyright 2003, Thierry Koblentz (TJKDesign.com)
' This line [above the HTML tag] is here to check if the Request() method returns a value.
' If nothing is returned, we use "red.asp" as the default value for the variable named "URL".
' If we end up with a string, we use that URL parameter value instead.
< % If Request.QueryString("URL") = "" Then URL = "red.asp" Else URL = Request.QueryString("URL") End If %>
<html>
<head>
<title>Going Dynamic!</title>
</head>
<frameset rows="240,*,270">
<frame name="top" src="green.asp" target="main">
<frame name="main" src="<%= URL %>">
<frame name="footer" src="yellow.asp" target="main">
<noframes>
<body>
The usual...
</body>
</noframes>
</frameset>
</html>
Building a Dynamic frameset using
ASP/JavaScript:
<%@LANGUAGE="JAVASCRIPT"%>
// Copyright 2003, Thierry Koblentz (TJKDesign.com)
// This line [above the HTML tag] is here to check if the Request() method returns a value.
// If nothing is returned, we use "red.asp" as the default value for the variable named "URL".
// If we end up with a string, we use that URL parameter value instead.
< %
if (String(Request.QueryString("URL")) == "undefined") {
URL = "red.asp";
}else{
URL = Request.QueryString("URL")};
%>
<html>
<head>
<title>Going Dynamic!</title>
</head>
<frameset rows="240,*,270">
<frame name="top" src="green.asp" target="main">
<frame name="main" src="<%= URL %>">
<frame name="footer" src="yellow.asp" target="main">
<noframes>
<body>
The usual...
</body>
</noframes>
</frameset>
</html>
MAKING IT HAPPEN
Calling the frameset and loading a specific document into the "main" frame.
Our Dynamic frameset becomes really Dynamic only when the "argument" it is looking for is found within the URL string. The way this "argument" is retrieved depends on the solution you chose [client-side or server-side].
Using the Client-Side solution:
The part of the URL string that will be used to set the value of the variable is sitting at the right hand side of the "?". Any string found after the "?" becomes a value for the src attribute of our "main" frame.
i.e. http://www.mySite.com/frameset.html?navigation.htm will load "navigation.htm" in the "main" frame of our frameset [frameset.html].
The following example produces a link that opens a frameset [frameset.html] with a specific document [http://www.TJKDesign.com/frames.asp] loaded into a specific frame ["main"]:
<a href="http://www.mySite.com/frameset.html?http://www.TJKDesign.com/tut.asp">Tutorial</a>
Note that it is possible to load absolute URIs as well.
As you may have already guessed, one can take advantage of this technique to avoid having pages show up in an unframed state into the browser window.
The simple script below [when placed between the head tags of a page] checks if the document is loaded into the topmost window - if it is - it calls the Dynamic frameset and loads itself into the "main" frame.
<script type="text/JavaScript">
// David Lavender suggested to include this line, to make sure the document does not ignore the anchor if it is present in the URI if ((top.location.href) && (top.location.hash))document.location = top.location.hash
if (self == self.parent){ // Copyright 2003, Thierry Koblentz (TJKDesign.com)
// this is the location of the active document
var myPage = self.document.location.href;
// for browsers that don't support the replace() method
if (document.images) {
top.location.replace('http://www.TJKDesign.com/frameset.html?' + myPage);
}else{
top.location.href = 'http://www.TJKDesign.com/frameset.html?' + myPage;
}
}
</script>
With Opera, the replace() method cannot be used with a relative URL so you'll need to change http://www.TJKDesign.com/frameset.html with the absolute path to your own frameset, the one containing the "Dynamic" code.
Using the Server-Side solution:
The part of the URL string that will be used to set the value of the variable is the value of the URL parameter.
Any string found after "URL=" becomes a value for the src attribute of our "main" frame.
i.e. http://www.TJKDesign.com/frameset.asp?URL=navigation.htm will load "navigation.htm" in the "main" frame of our frameset [frameset.asp].
The following link opens a frameset [frameset.asp] with a specific document [http://www.TJKDesign.com/tut.asp] loaded into a specific frame ["main" in our example]:
<a href="http://www.mySite.com/frameset.asp?URL=http://www.TJKDesign.com/tut.asp">Tutorial</a>
Note that it is possible to load absolute URLs as well.
As you may have already guessed, one can take advantage of this technique to avoid having pages show up in an unframed state into the browser window.
The simple script below [when placed between the head tags of a page] checks if the document is loaded into the topmost window - if it is - it calls the Dynamic frameset and loads itself into the "main" frame.
<script type="text/JavaScript">
if (self == self.parent){ // Copyright 2003, Thierry Koblentz (TJKDesign.com)
// this is the location of the active document
var myPage = self.document.location.href;
// for browsers that don't support the replace() method
if (document.images) {
top.location.replace('http://www.TJKDesign.com/frameset.asp?URL=' + myPage);
}else{
top.location.href = 'http://www.TJKDesign.com/frameset.asp?URL=' + myPage;
}
}
</script>
With Opera, the replace() method cannot be used with a relative URL so you'll need to change http://www.TJKDesign.com/frameset.asp with the path to your own frameset, the one containing the "Dynamic" code.
RAISING THE BAR
Building the frameset on the fly each time a link is clicked.
It is possible to take the whole idea to another level.
We can make calls to the Dynamic frameset each time the user clicks on a link inside a document.
Doing so, the URL in the browser's address bar holds the frameset state [reference to the exact layout] inside the browser's window.
With this technique we can fix 2 problems [related to frames] at once:
- refreshing [reloading] a frameset,
- bookmarking a frameset.
The easiest way to achieve this is to use 2 of the attributes of the 'A' tag ['href' and 'target'].
The problem though, is that the 'href' attribute needs to be set to an absolute URL that consists of:
- the absolute path to your Dynamic
frameset, - the "?" or the "?URL=" string depending on the kind of Dynamic
framesetyou're using [client or server-side], - the absolute path to the
documentyou're linking to.
This can be an issue for 2 reasons:
- the URL in the address bar looks pretty "ugly",
- typing such long URLs can lead to typos and errors.
Even though HTTP/1.1 does not specify any requirement for URL length, there is a limit in MSIE of 2,083 characters.
Netscape claims that the only restriction is of 32kb (characters) due to the MS OS...
A solution to the former:
One can nest the entire frameset into a new one. Be aware that this workaround adds a new branch to the frames tree and that each former reference to "_top" must be changed to "_parent".
A solution to the latter:
A short JavaScript function can simplify the process of setting long URLs and target attributes for every link by parsing all the 'A' tags to rebuild the array with the appropriate URL format and target values.
It means that you don't have to worry about the proper "syntax" to call the Dynamic frameset and a specific document, the function will do that for you.
ie. the code that appears like this in your page:<a href="portfolio.html">our portfolio</a> could be "interpreted" like this by the browser once the page is loaded:
<a href="http://www.mySite.com/frameset.html?http://www.mySite.com/services/portfolio.html" target="_top">our portfoli</a>
Below is the function to put between the head tags of your document:
[the onLoad event of the body tag is used to trigger it - ie. onload="TJKLinks()"]
The script overwrites the target value set at the frame or document level.
<script type="text/JavaScript">
function TJKLinks() { // Copyright 2003, Thierry Koblentz (TJKDesign.com)
var myLinks, i = 0;
var howManyLinks= document.links.length ;
while (howManyLinks > 0 ) {
myLinks = document.links[i++];
myLinks.href = 'http://www.TJKDesign.com/frameset.html?' + myLinks.href;
myLinks.target = '_top';
howManyLinks --;
}
}
</script>
With Opera, the replace() method cannot be used with a relative URL so you'll need to change http://www.TJKDesign.com/frameset.html? with the absolute path to your own frameset [keeping the "?"].
If you use the server-side script instead of the client-side one, then you'll need to replace http://www.TJKDesign.com/frameset.html? with the absolute path to your .asp frameset [keeping the "?"] and then add URL=to that string.
Because this technique reloads every frame, it can bring up issues related to refreshing documents [i.e., anchor positions are lost, onload events are fired again, etc.].
To "skip" the function when creating a link, one can use some JavaScript within the 'A' tag, i.e.,... onclick="top.frames[2].location.href='footer.html';return false;" ...
The "return false" statement is needed to ignore the value of the "href" attribute within the 'A' tag.





















