The Navigation Bar Files

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 Purely ASP Navigation Bar

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
...

The Plain JavaScript Navigation Bar

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.

The Navigator 4 Navigation Bar

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.

Changing the Image Source

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 Internet Explorer 4 Navigation Bar

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 Dynamic HTML Navigation Bar File

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">
 &nbsp;<A HREF="main_ie4.asp" TARGET="mainframe">
  <SPAN CLASS="sublink">Contact</SPAN></A><BR>
 &nbsp;<A HREF="main_ie4.asp" TARGET="mainframe">
  <SPAN CLASS="sublink">Legal</SPAN></A><BR>
 &nbsp;<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">
 &nbsp;<A HREF="books/booklist.asp" TARGET="mainframe">
  <SPAN CLASS="sublink">All books</SPAN></A><BR>
 &nbsp;<A HREF="books/booklist.asp" TARGET="mainframe">
  <SPAN CLASS="sublink">Previews</SPAN></A><BR>
 &nbsp;<A HREF="books/booklist.asp" TARGET="mainframe">
  <SPAN CLASS="sublink">Downloads</SPAN></A><BR>
 &nbsp;<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

© 1998 by Wrox Press. All rights reserved.