Lab Notes Ten: Dynamic HTML, stylesheets and Javascript.

This lab we will study:

The purpose of the project is to expose you to a more complex aspect of HTML.

C.1 Stylesheet Fundamentals

Summary:

Here are some images we will need:
  1. company_name.gif
  2. feature.gif
  3. logo.jpg
  4. main_nav.gif
  5. resource_nav.gif
  6. search_go.gif
  7. teaser2.gif
  8. teaser3.gif
  9. teaser_fullstory.gif
  10. teaser_more.gif
Create these images in Photoshop or whatever.

Determine where the home page will be, for example:

http://burrowww.cs.indiana.edu:20006/shelley
Then start working on the index.html:

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  position: absolute;
  top: 20px;
  left: 20px;
}

</style>

</head>
<body bgcolor="#ffffff">

</body>
</html>
All the styles and layers are declared inside the <STYLE> and </STYLE> tags. A layer contains any chunk of HTML. A style is a modification of an HTML tag. We're declaring a layer called companyName. The # means that the contents of the layer are spelled out somewhere else in the document. It's vital that we place all the information about the layers inside curly braces, and end each line with a semicolon.

Position information here says that we're going to tell the layer exactly where it should go, and that is 20 pixels over from the left edge of the browser window and 20 pixels down from the top edge of the browser window.

We determine the content of companyName inside the <body> of the page.

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  position: absolute;
  top: 20px;
  left: 20px;
}

</style>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."> 
</div> 

</body>
</html>
The <DIV> tag with an ID=name attribute contains everything that goes in a certain layer. Here we're determining the content of the layer companyName. The only thing in this layer is a single image.

Let's now add the code for the other five layers:

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo               { position: absolute; top:   9px; left: 304px; } 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 


</style>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."> 
</div>

</body>
</html>
Notice a layer's information can be on the same line as long as there are semicolons between the attributes. The content of these layers is determined inside the <BODY>, as before.

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo               { position: absolute; top:   9px; left: 304px; } 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 

</style>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0>
</div>

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="mainNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/main_nav.gif"
     width="561"
     height="42"
     alt="Main Navigation"
     border=0
     usemap="#mainnav">
</div>

<div id="resourceNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/resource_nav.gif"
     width="396"
     height="31"
     alt="Resource Navigation"
     border=0
     usemap="#resnav">
</div>

<div id="feature">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/feature.gif"
     width="571"
     height="299"
     alt="Salsa!"
     border=0
     usemap="#feature">
</div>

</body>
</html>
We just added the definitions of each of the layers. The page is now ready. Let's check it; whoops! Some of the images are overlapping others, so we're not done yet. Let's see what's happening and why. Web browsers stack layers according according to where the layer occurs in the code. Layers that occur first (such as companyName) are placed on the bottom, and layers that occur later in the code (such as logo) are displayed on top of whatever's already there.

Thus the image of the logo is above the company name, so it overlaps and it hides part of the Shelley Biotechnologies image. There are two ways to get around this:

  1. Make the top image transparent so that the bottom image shows through. But that won't work here because the logo is a JPEG, and you can't get transparency out of a JPEG. So you have to

  2. Change the layer stacking order using something new called the z-index.
    #companyName
    {
      z-index: 1;
      position: absolute; 
      top: 20px;
      left: 20px; 
    } 
    The z-index tells the browser which layer is on top. If you don't say which z-index a layer is, it's assumed to be on a z-index of zero, and the browser stacks the layers according to their order in the code.

    Make this change and let's check the code.

But there are a couple of issues:

To avoid the second problem simply place the logo before the company name.

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0> 
</div>
An alternative solution is to explicitly set the z-index of the logo to zero.

#companyName
{
  z-index:        1; 
  position: absolute;
  top:          20px;
  left:         20px;
}

#logo  
{ 
  z-index:         0; 
  position: absolute; 
  top:           9px; 
  left:        304px; 
} 
To avoid the first problem make one color transparent. (If you just want to see what's transparent and what not use a red background). Anyway, the page now is complete and looks
like this
Let's move on to the next stage.

Let's say that the Shelley Biotech Web site is huge: over 5000 pages and growing on a weekly basis. When visitors are confronted with a site as large as Shelley's, they will often try to find some information via the site's search engine rather than trying to navigate through the site. To that end, let's make their searching a little easier: When they click on Search, we can send them to a separate search page, but it would be quicker and more convenient to the visitor to pop up a small window that has a short HTML form and a Go Search button. To do this we add the following code to the (new) Shelley homepage. Copy your index.html to one.html and two.html then make the following changes to the second one:

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  z-index: 1; 
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo  
{ 
  z-index:         0; 
  position: absolute; 
  top:           9px; 
  left:        304px; 
} 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 

#companyName        { position: absolute; top:  16px; left:  29px; } 


#search 
{
  z-index: 5;
  position: absolute;
  top: 280px; 
  left: 150px;
  visibility: visible; 
}
</style>

<script language="javascript">
function showLayer(layerName) 
{
  document.layers[layerName].visibility = 'visible'; 
}

function hideLayer(layerName)
{
  document.layers[layerName].visibility = 'hidden'; 
}
</script>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0> 
</div>

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="mainNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/main_nav.gif"
     width="561"
     height="42"
     alt="Main Navigation"
     border=0
     usemap="#mainnav">
</div>

<div id="resourceNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/resource_nav.gif"
     width="396"
     height="31"
     alt="Resource Navigation"
     border=0
     usemap="#resnav">
</div>

<div id="feature">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/feature.gif"
     width="571"
     height="299"
     alt="Salsa!"
     border=0
     usemap="#feature">
</div>

<div id="search">

<p>
<h3>Search the Shelley Site</h3>
<form action="cgi-bin/search.pl" method="post">
  <table>
    <tr> <td valign=middle><input type=text size=30 name=searchString></td>
         <td valign=middle><input type=image src=search_go.gif border=0></td>
    </tr>
  </table>
</form>
<p> 
<a href="javascript:hideLayer('search')">Close this window</a>
</p>

</div>

</body>
</html>
You should test it now. One can see the search window, as well as through it.

Place the whole navigation layer inside a table with a white background.

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  z-index: 1; 
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo  
{ 
  z-index:         0; 
  position: absolute; 
  top:           9px; 
  left:        304px; 
} 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 

#companyName        { position: absolute; top:  16px; left:  29px; } 


#search 
{
  z-index: 5;
  position: absolute;
  top: 280px; 
  left: 150px;
  visibility: visible; 
}
</style>

<script language="javascript">
function showLayer(layerName) 
{
  document.layers[layerName].visibility = 'visible'; 
}

function hideLayer(layerName)
{
  document.layers[layerName].visibility = 'hidden'; 
}
</script>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0> 
</div>

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="mainNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/main_nav.gif"
     width="561"
     height="42"
     alt="Main Navigation"
     border=0
     usemap="#mainnav">
</div>

<div id="resourceNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/resource_nav.gif"
     width="396"
     height="31"
     alt="Resource Navigation"
     border=0
     usemap="#resnav">
</div>

<div id="feature">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/feature.gif"
     width="571"
     height="299"
     alt="Salsa!"
     border=0
     usemap="#feature">
</div>
       
<div id="search">
<p>
<table bgcolor=white border><tr><td>
<h3 align=center>Search the Shelley Site</h3>
<form action="cgi-bin/search.pl" method="post">
  <table>
    <tr> <td valign=middle><input type=text size=30 name=searchString></td>
         <td valign=middle><input type=image src=search_go.gif border=0></td>
    </tr>
  </table>
</form>
<p align=center> 
<a href="javascript:hideLayer('search')">Close this window</a>
</p>
</td></tr></table></div>

</html>
Now that we see the window properly and have a way to send it away let's make it invisible to start with and have the search picture generate pop it up. So we make the following changes, illustrated below in blue:
<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  z-index: 1; 
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo  
{ 
  z-index:         0; 
  position: absolute; 
  top:           9px; 
  left:        304px; 
} 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 

#companyName        { position: absolute; top:  16px; left:  29px; } 


#search 
{
  z-index: 5;
  position: absolute;
  top: 280px; 
  left: 150px;
  visibility: hidden; 
}
</style>

<script language="javascript">
function showLayer(layerName) 
{
  document.layers[layerName].visibility = 'visible'; 
}

function hideLayer(layerName)
{
  document.layers[layerName].visibility = 'hidden'; 
}
</script>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0> 
</div>

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="mainNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/main_nav.gif"
     width="561"
     height="42"
     alt="Main Navigation"
     border=0
     usemap="#mainnav">
</div>

<div id="resourceNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/resource_nav.gif"
     width="396"
     height="31"
     alt="Resource Navigation"
     border=0
     usemap="#resnav">
     <map name="resnav">
       <area shape  = "rect" 
             coords = "0,0,100,31" 
             href   = "javascript:showLayer('search')"
       >
     </map>
</div>

<div id="feature">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/feature.gif"
     width="571"
     height="299"
     alt="Salsa!"
     border=0
     usemap="#feature">
</div>

<div id="search">
<p>
<table bgcolor=white border><tr><td>
<h3 align=center>Search the Shelley Site</h3>
<form action="cgi-bin/search.pl" method="post">
  <table>
    <tr> <td valign=middle><input type=text size=30 name=searchString></td>
         <td valign=middle><input type=image src=search_go.gif border=0></td>
    </tr>
  </table>
</form>
<p align=center> 
<a href="javascript:hideLayer('search')">Close this window</a>
</p>
</td></tr></table></div>
</html>
Let's add a few more layers now.

<html>
<head>
<title>Welcome to Shelley Biotechnologies, Inc.</title>

<style type="text/css">

#companyName
{
  z-index: 1; 
  position: absolute;
  top: 20px;
  left: 20px;
}

#logo  
{ 
  z-index:         0; 
  position: absolute; 
  top:           9px; 
  left:        304px; 
} 

#mainNavigation     { position: absolute; top: 138px; left:  25px; } 

#resourceNavigation { position: absolute; top: 173px; left: 173px; } 

#feature            { position: absolute; top: 194px; left:  19px; } 

#companyName        { position: absolute; top:  16px; left:  29px; } 


#search 
{
  z-index: 5;
  position: absolute;
  top: 280px; 
  left: 150px;
  visibility: hidden; 
}

#productsNav 
{ 
  z-index: 5; 
  position: absolute;
  top: 180px; 
  left: 25px;
  visibility: hidden;  
}

#trainingNav 
{ 
  z-index: 5; 
  position: absolute;
  top:  180px; 
  left: 150px;
  visibility: hidden;  
} 

</style>

<script language="javascript">

function showLayer(layerName) 
{
  document.layers[layerName].visibility = 'visible'; 
}

function hideLayer(layerName)
{
  document.layers[layerName].visibility = 'hidden'; 
}
</script>

</head>
<body bgcolor="#ffffff">

<div id="companyName">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/company_name.gif" 
     height="128"
     width="428"
     alt="Shelley Biotechnologies, Inc."
     border=0> 
</div>

<div id="logo">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/logo.jpg"
     width="275"
     height="117"
     alt="Shelley Logo"
     border=0>
</div>

<div id="mainNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/main_nav.gif"
     width="561"
     height="42"
     alt="Main Navigation"
     border=0
     usemap="#mainnav">

     <map name="mainnav">
       <area shape="rect" coords="0,0,60,42" href="javascript:showLayer('productsNav')">
       <area shape="rect" coords="120,0,200,42" href="javascript:showLayer('trainingNav')">
     </map>
</div>

<div id="resourceNavigation">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/resource_nav.gif"
     width="396"
     height="31"
     alt="Resource Navigation"
     border=0
     usemap="#resnav">

     <map name="resnav">
       <area shape="rect" coords="0,0,100,31" href="javascript:showLayer('search')">
     </map>
</div>

<div id="feature">
<img src="http://burrowww.cs.indiana.edu:20006/shelley/feature.gif"
     width="571"
     height="299"
     alt="Salsa!"
     border=0
     usemap="#feature">
</div>

<div id="search">
       <p>
       <table bgcolor=white border><tr><td>
       <h3 align=center>Search the Shelley Site</h3>
       <form action="cgi-bin/search.pl" method="post">
         <table>
           <tr> <td valign=middle><input type=text size=30 name=searchString></td>
                <td valign=middle><input type=image src=search_go.gif border=0></td>
           </tr>
         </table>
       </form>
       <p align=center> 
       <a href="javascript:hideLayer('search')">Close this window</a>
       </p>
       </td></tr></table></div>

<div id="productsNav">
<table bgcolor="#ffffff" border cellpadding=4><tr><td>
  <h3 align=center> Products </h3> 
  <a href="products/portable">Portable BioLab</a><br>
  <a href="products/accessories">Portable Biolab Accessories</a><br>
  <a href="products/education">Educational Products</a><br>
  <a href="products/corporate">Corporate BioLabs</a><br>
  <a href="products/enterprise">Enterprise BioLabs</a><br>
  <p><a href="store/">How to order</a></p> 
  <p><a href="javascript:hideLayer('productsNav')">Close this window</a></p>
</td></tr></table>
</div>

<div id="trainingNav">
<table bgcolor="#ffffff" border cellpadding=4><tr><td>
  <h3 align=center> Training </h3> 
  <a href="training/begin">Genetic Engineering for Beginners</a><br>
  <a href="training/intermediate">Intermediate Genetic Engineering</a><br>
  <a href="training/advanced">Advanced Genetic Engineering</a><br>
  <a href="training/prof">Professor Track Biogenesis</a><br>
  <a href="training/rdna">rDNA Refresher Courses</a><br>
  <p><a href="training/schedule">Build your training schedule</a></p> 
  <p><a href="javascript:hideLayer('trainingNav')">Close this window</a></p>
</td></tr></table>
</div>

</html>
We're not done yet.

We change the showLayer method to keep up to one window open at all times:

<script language="javascript">
oldLayer = ""; 
function showLayer(layerName) 
{
  if (oldLayer) {
    document.layers[oldLayer].visibility = 'hidden';     
  }
  document.layers[layerName].visibility = 'visible'; 
  oldLayer = layerName; 
}

function hideLayer(layerName)
{
  document.layers[layerName].visibility = 'hidden'; 
}
</script>
And the result is here.

But this does not work with Internet Explorer.

What do we do?

What is the problem?

Netscape and Internet Explorer version 4 browsers implement DHTML differently: They need different JavaScript syntax to do the same thing. This is annoying but unavoidable. We have to code the Shelley homepage so that both browsers can see and understand the DHTML.

Here's a browser difference that you'll be seing the most.

In Netscape:

document.layers['search'].visibility = 'visible';
In Internet Explorer:
document.all['search'].style.visibility = 'visible';
These two statements are close, but not close enough to work in the other's browser. Fortunately, you don't have to code two totally separate functions for each browser. There's an easier way, although it makes your code more difficult to read.

First, here is the Internet Explorer version of the page.

It does not work with Netscape.

The eval() method in JavaScript is the best way to code DHTML for both Netscape and IE browsers at the same time. It does this by letting you dynamically generate your own JavaScript. Here's the code:

<script language="javascript">

layerRef = ""; 
styleRef = "";

if (navigator.appName == "Netscape") 
{
  layerRef = ".layers";   
  styleRef = ""; // redundant 
} 
else // must be MSIE
{
  layerRef = ".all"; 
  styleRef = ".style"; 
}

oldLayer = ""; 
function showLayer(layerName) 
{
  if (oldLayer) {
    // document.layers[oldLayer].visibility = 'hidden'; 
    eval( 
       "document" + 
               layerRef + 
                     "['" + 
                       oldLayer + 
                            "']" + 
                                styleRef  + 
                                ".visibility = " + 
                                             "'hidden';"
        ); 
    // also accounting for the MSIE syntax below:
    // document.all[oldLayer].style.visibility = 'hidden'; 
  }
  // document.layers[layerName].visibility = 'visible'; 
  eval( "document" + layerRef + "['" + layerName + 
        "']" + styleRef  + ".visibility = 'visible';"
      ); 
  oldLayer = layerName; 
}

function hideLayer(layerName)
{
  // document.layers[layerName].visibility = 'hidden'; 
  eval( "document" + layerRef + "['" + layerName + 
        "']" + styleRef  + ".visibility = 'hidden';"
      ); 
}
</script>
Here's the document that works with both browsers.

Lab Assignment to follow.


Last updated on Oct 30, 2001, by Adrian German for A348/A548