The four different navigation bars use four different techniques to display information that indicates to the user which section of the site they are currently visiting. The four techniques are:
nav_any.asp |
Button images selected by reloading a purely server side ASP page each time |
nav_js.htm |
Button images selected by client-side script as the page is reloaded each time |
nav_nav4.htm |
Button images selected by client-side script without reloading the page |
nav_ie4.htm |
Collapsible text links changed by client-side script without reloading the page |
The navigation bar for non script-enabled browsers is the simplest of the four techniques, and was described in the frameset example in Chapter 3. Each button image reloads the entire frameset (the page default.asp
), specifying the section to be shown in the query string. As default.asp
builds the frameset, it passes on the section name to the navigation bar again—remember the code in default.asp
that creates the URLs for the simple site is:
'set defaults for any browser (this is in default.asp)
strBrowser = "any"
strNavBar = "nav_any.asp?section=" & strSection
The following is part of the nav_any.asp file, showing the way that the section name is used to decide which button image to include in the final page:
<% LANGUAGE=VBSCRIPT %>
<%
strSection = Request.QueryString("section")
If Len(strSection) = 0 Then strSection = "home"
%>
...
<A HREF="default.asp?section=home" TARGET="_top"><IMG BORDER=0
<% If strSection = "home" Then %>
SRC="/images/home_dn.gif"
<% Else %>
SRC="/images/home_up.gif"
<% End If %>
WIDTH="81" HEIGHT="25" VSPACE="1" ALT="Web-Developer Home Page"></A><BR>
...
similar code for the other button images
...
If we are dealing with a browser that supports JavaScript, we use the other technique that we described in detail in the Chapter 3 version of our frameset. We use client-side script to write the URL of the appropriate button image into the page as it's being loaded. To tell which one to use, the script looks to see which page is currently displayed in the main frame:
<HTML>
<BODY BGCOLOR=#CC3333>
...
<A HREF="main_js.asp" TARGET="mainframe">
<SCRIPT LANGUAGE=JavaScript>
if (parent.frames[1].location.href.indexOf('main_js.asp') != -1)
document.write('<IMG BORDER=0 SRC="/images/home_dn.gif" WIDTH="81" ' +
'HEIGHT="25" VSPACE="1" ALT="Web-Developer Home Page"/>')
else
document.write('<IMG BORDER=0 SRC="/images/home_up.gif" WIDTH="81" ' +
'HEIGHT="25" VSPACE="1" ALT="Web-Developer Home Page"/>');
</SCRIPT>
</A>
...
similar code for the other button images
...
For this to work, the navigation page must be reloaded each time we want to change the images that are displayed. However it avoids the need for any other server interaction. This is an HTML page (nav_js.htm
), and so does not use ASP.
In Navigator 4 (and in fact in Navigator 3 and Internet Explorer 4) we can take advantage of the fact that it's possible to change the src
property of an image on the loaded page, and have the new image displayed immediately. This allows us to swap the button images without reloading the page. Here's the nav_nav4.htm
navigation bar page. We've removed some of the repeated code for the buttons to make it easier to see what's going on:
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
function updateNavbar(strSection) {
arrImages = document.images
for (i = 0; i <= arrImages.length - 1; i++) {
intPosn = arrImages[i].src.indexOf('_dn.gif');
strImagePath = arrImages[i].src.substr(0, intPosn);
if (arrImages[i].src.indexOf('_dn.gif') != -1)
arrImages[i].src = strImagePath + '_up.gif';
}
if (strSection == 'home') arrImages[1].src = '/images/home_dn.gif';
if (strSection == 'books') arrImages[2].src = '/images/samp_dn.gif';
if (strSection == 'resources') arrImages[3].src = '/images/resor_dn.gif';
if (strSection == 'reference') arrImages[4].src = '/images/refer_dn.gif';
if (strSection == 'search') arrImages[5].src = '/images/srch_dn.gif';
if (strSection == 'sitemap') arrImages[6].src = '/images/smap_dn.gif';
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR=#CC3333>
<CENTER>
<IMG BORDER=0 SRC="/images/webdevsm.gif" VSPACE="10" ALT="web-dev.wrox"><BR>
<A HREF="main_nav4.asp" TARGET="mainframe">
<IMG BORDER=0 SRC="/images/home_up.gif" ALT="Web-Developer Home Page"></A>
<A HREF="books/booklist.asp" TARGET="mainframe">
<IMG BORDER=0 SRC="/images/samp_up.gif" ALT="Books and Samples"></A><BR>
...
similar code for the other button images
...
<A HREF="main_nav4.asp" TARGET="_top">
<IMG BORDER=0 SRC="/images/noframes.gif" ALT="Turn Frames Off"></A>
</CENTER>
<LAYER VISIBILITY="HIDDEN">
<IMG SRC="/images/home_up.gif"> <IMG SRC="/images/samp_dn.gif">
<IMG SRC="/images/resor_dn.gif"><IMG SRC="/images/refer_dn.gif">
<IMG SRC="/images/srch_dn.gif"> <IMG SRC="/images/smap_dn.gif">
</LAYER>
</BODY>
</HTML>
Each button image is a hyperlink that loads the appropriate page into the main window. Notice how we use a <LAYER>
element at the end of the page, with the VISIBILITY
attribute set to HIDDEN
, to pre-load and cache the other button images. This is very similar to the way we did it with IE4, in the frameset example back in Chapter 2. There, we used the STYLE="visibility:hidden"
attribute in an <IMG>
tag.
To change the image source, we have a JavaScript function named updateNavbar
in the <HEAD>
of the page. This accepts a string parameter that is the name of the section that is currently displayed in the main window. The code has to change the source of the button images so that the correct one is shown 'depressed'.
Here's the code again. The first part simply iterates through all the images in the document, using the images
collection (or array). For each one, it makes sure any image that has a src
property value ending in '_dn.gif
' is changed to the equivalent image ending with '_up.gif
':
<SCRIPT LANGUAGE="JavaScript">
function updateNavbar(strSection) {
arrImages = document.images
for (i = 0; i <= arrImages.length - 1; i++) {
intPosn = arrImages[i].src.indexOf('_dn.gif');
strImagePath = arrImages[i].src.substr(0, intPosn);
if (arrImages[i].src.indexOf('_dn.gif') != -1)
arrImages[i].src = strImagePath + '_up.gif';
}
...
Then it examines the value of strSection sent as the parameter to the function, and changes the appropriate image's src property to the equivalent 'down' image:
...
if (strSection == 'home') arrImages[1].src = '/images/home_dn.gif';
if (strSection == 'books') arrImages[2].src = '/images/samp_dn.gif';
if (strSection == 'resources') arrImages[3].src = '/images/resor_dn.gif';
if (strSection == 'reference') arrImages[4].src = '/images/refer_dn.gif';
if (strSection == 'search') arrImages[5].src = '/images/srch_dn.gif';
if (strSection == 'sitemap') arrImages[6].src = '/images/smap_dn.gif';
}
</SCRIPT>
The result is that we have a high-performance page that works like a compiled application, rather than a Web page. The changes to the image are so quick that they almost look like real 'Windows-style' buttons.
The final navigation bar is the one designed to take advantage of Dynamic HTML in Internet Explorer 4 and above. We took a different approach here, to show you another technique for providing navigation information. Instead of using button images, we provide a set of text links for each section of the site. When you go to one of the sections (i.e. when that section page is displayed in the main window), the navigation bar provides a list of pages that are available within that section:
In fact, we only have one page for each section, so the other links just point to this page as well, but you can see the principle behind it. It can act as a site map as well as a navigation bar. Our example 'closes' (contracts) each section list when you select another one, so that only one is visible at a time. However, you could change it so that they stayed open until clicked again if you wished, providing a more traditional 'collapsible tree' type of structure.
The navigation bar page contains: a script section (we're using VBScript here, because we know the page will be running on IE4 or better); a style definition section that sets the appearance of the text; and then a set of text links for each main topic—where we had buttons in the earlier examples. Here's the complete code of the page, with the exception of some of the links. We've removed these to avoid excessive duplication, and to make it easier to see what's going on:
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub updateNavbar(strSection)
On Error Resume Next
Set colDivs = document.all.tags("DIV")
For Each objDiv In colDivs
objDiv.style.display = "none"
Next
Set objDiv = document.all("div_" & strSection)
objDiv.style.display = ""
End Sub
'-->
</SCRIPT>
<STYLE>
.mainlink {font-family:Tahoma,sans-serif; color:white; font-size:12px;
font-weight:bold; text-decoration:none; line-height:150%}
.sublink {font-family:Tahoma,sans-serif; color:white; font-size:12px;
font-weight:normal; text-decoration:none; list-style-type:none}
</STYLE>
</HEAD>
<BODY BGCOLOR=#CC3333>
<CENTER>
<IMG BORDER=0 SRC="/images/webdevsm.gif" WIDTH=82 HEIGHT=76 VSPACE="10">
<BR>
</CENTER>
<A HREF="main_ie4.asp" TARGET="mainframe">
<SPAN CLASS="mainlink">Home</SPAN></A>
<DIV ID="div_home" STYLE="display:none">
<A HREF="main_ie4.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Contact</SPAN></A><BR>
<A HREF="main_ie4.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Legal</SPAN></A><BR>
<A HREF="main_ie4.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Other</SPAN></A><BR>
</DIV>
<A HREF="books/booklist.asp" TARGET="mainframe">
<SPAN CLASS="mainlink">Samples</SPAN></A>
<DIV ID="div_books" STYLE="display:none">
<A HREF="books/booklist.asp" TARGET="mainframe">
<SPAN CLASS="sublink">All books</SPAN></A><BR>
<A HREF="books/booklist.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Previews</SPAN></A><BR>
<A HREF="books/booklist.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Downloads</SPAN></A><BR>
<A HREF="books/booklist.asp" TARGET="mainframe">
<SPAN CLASS="sublink">Updates</SPAN></A><BR>
</DIV>
...
... other links here ...
...
<A HREF="mainpage.asp" TARGET="_top">
<SPAN CLASS="mainlink">No Frames</SPAN></A>
</BODY>
</HTML>
Each main topic link is followed by a <DIV>
element that contains the sub-links to pages within that topic area (in our example they just point to the main topic, as we don’t have any sub-topic pages). Each <DIV>
has an ID
that we can refer to it by. The ID
is built up from the text div_
followed by the section name that will be provided by each content page as it loads. There is also a STYLE
attribute that sets the display
property to "none"
—meaning that the complete <DIV>
element will not be included in the visible page when it's rendered by the browser. The result is that only the top-level headings are visible in the page. The list is 'collapsed'.
As in the Navigator 4 example, each content page calls the updateNavbar
subroutine when it loads, and specifies which topic it covers as a parameter. Our subroutine only has to change the display
style properties of the <DIV>
elements to make the appropriate one visible. Here's the code again. It creates a collection of all the <DIV>
elements in the page and sets all their display
style properties to "none"
. Then it sets the display
style properties of the particular one we want to show to an empty string—effectively 'turning the property off', which makes it appear in the page as normal:
Sub updateNavbar(strSection)
On Error Resume Next
Set colDivs = document.all.tags("DIV")
For Each objDiv In colDivs
objDiv.style.display = "none"
Next
Set objDiv = document.all("div_" & strSection)
objDiv.style.display = ""
End Sub