JavaScript Editor JavaScript Validator     JavaScript Editor 



Team LiB
Previous Section Next Section

Chapter 12

In this chapter we looked at Dynamic HTML (DHTML), in which we use scripting languages, like JavaScript, to open up the page to manipulation after the page has loaded to enhance user interaction.

Question 1

Q: 

 

Create a series of images, each of which is a button linking to a different page on your website. When the mouse pointer rolls over an image, display some text somewhere on the page that describes what the users would find if they follow the link. For example, an image saying "What's New" might have the description, "Find out what has been added to the website since your last visit." When the mouse pointer rolls off, the descriptive text should disappear. Your page must work with IE 4+ and NN 4.x.

A: 
<html>
<head>
<script language=JavaScript>
    
var descriptions = new Array();
descriptions[0] = "<P>See what's been added to the website since your last

        visit</P>";
descriptions[1] = "<P>Find out more about me and this website</P>";
descriptions[2] = "<P>Check out the interesting and useful links on this
        page</P>";
    
function showDescription(descriptionIndex)
{
   if (document.all)
   {
      DescriptionDiv.style.visibility = "visible";
      DescriptionDiv.innerHTML = descriptions[descriptionIndex];
   }
   else
   {
      document.DescriptionDiv.visibility = "visible";
      document.DescriptionDiv.document.open();
      document.DescriptionDiv.document.write("<div
          class='DescriptionDivStyle'>");
      document.DescriptionDiv.document.write(descriptions[descriptionIndex]);
      document.DescriptionDiv.document.write("</div>");
      document.DescriptionDiv.document.close();
   }
}
    
function clearDescription()
{
   if (document.all)
   {
      DescriptionDiv.style.visibility = "hidden";
   }
   else
   {
      document.DescriptionDiv.visibility = "hidden";
   }
}
</script>
<style>
    
   div
      {
         border-width: thin;
         border-style: ridge;
         border-color: red;
         width: 250px;
         height: 70px;
         visibility: hidden;
      }
    
      .DescriptionDiv
      {
         position: absolute;
         left: 120px;
         top: 50px;
    
      }
</style>
    
</head>
<body>
    
<A href="WhatsNew.htm"
   onmouseover="showDescription(0)"
   onmouseout="clearDescription()">
   <img src="WhatsNew.jpg" border=0></A>
<br>
<A href="AboutMe.htm"
   onmouseover="showDescription(1)"
   onmouseout="clearDescription()">
   <img src="AboutMeButton.jpg" border=0></A>
<br>
<A href="InterestingLinks.htm"
   onmouseover="showDescription(2)"
   onmouseout="clearDescription()">
   <img src="InterestingLinks.jpg" border=0></A>
    
<div id=DescriptionDiv name=DescriptionDiv class="DescriptionDiv">
</div>
    
</body>
</html>

Let's look at this page in more detail, starting with the style sheet definition where we define border styles, dimensions, positioning, and visibility. The first style defines style for all <div> tags on the page; the second defines a style class called DescriptionDiv.

Because <img> tags don't support the onmouseover and onmouseout events in NN 4, we have to use the mouse events of the <A> tag.

<A href="WhatsNew.htm"
   onmouseover="showDescription(0)"
   onmouseout="clearDescription()">
   <img src="WhatsNew.jpg" border=0></A>

Finally we have a <div> that will contain the text we wish to display.

<div id=DescriptionDiv name=DescriptionDiv class="DescriptionDiv">
</div>

At the top of the script block we define a new array called descriptions that holds the descriptions we'll display when the user rolls the pointer over a menu button. Because it's declared outside of any function, it has global scope and will be accessible from all functions in the page.

var descriptions = new Array();
descriptions[0] = "<P>See what's been added to the website since your last

        visit</P>";
descriptions[1] = "<P>Find out more about me and this website</P>";
descriptions[2] = "<P>Check out the interesting and useful links on this
        page</P>";

The first function declared is showDescription(), called by the onmouseover event handler of the <A> tag surrounding the image. It takes just one parameter, descriptionIndex, which is the index value for the description in the descriptions array.

How we actually insert HTML after the page has loaded differs between IE 4+ and NN 4, so we check to see if document.all returns a value. If it does this must be IE 4+ since only IE 4+ supports the all property of the document object. For IE, we simply make the <div> visible, then set its innerHTML to the string contained inside our descriptions array, which replaces any previous HTML in there.

If this is NN 4, we again make the <div> visible and write our HTML to the document object contained inside the Layer object that represents our Div. The document.open() clears any previous HTML in there.

Although the IE and NN versions may look similar in that they both appear to be accessing the Div object of the <div> tag, they are in fact very different. NN 4 does not have a Div object but instead represents any absolutely positioned tags with a Layer object, regardless of their actual tag type. So document.DescriptionDiv.visibility is actually changing the visibility property for the Layer object created for that <div>.

The final function, clearDescription(), called by the onmouseout event handler of the <A> tag surrounding the image, works in a similar way. We first check if this is IE or NN. If it's IE, we hide the Div using its style property, and if it's NN, we access the Layer object representing the <div> and set its visibility property to hidden.

Question 2

Q: 

 

Create an image that says "Welcome" and floats around the page. When the user's mouse pointer rolls over the image, change it so it displays "Click For What's New." When clicked it should take the user to a page detailing new additions to the website. The solution must work with both IE 4+ and with NN 4.x.

A: 
<html>
<head>
<script language=JavaScript>
    
var isIE;
    
var floatingDivHeight = 65;
var floatingDivWidth = 265;
    
var timerId;
var screenWidth;
var screenHeight;
var horizontalMovement = Math.ceil(Math.random() * 6);
var verticalMovement = Math.ceil(Math.random() * 3);
    
function startTimer()
{
   timerId = window.setInterval("moveDiv()",100);
    
   if (document.all)
   {
      floatingDiv.style.left = "6px";
      floatingDiv.style.top = "6px";
    
      screenWidth = document.body.clientWidth;
      screenHeight = document.body.clientHeight;
    
      isIE = true;
   }
   else
   {
      screenWidth = window.innerWidth;
      screenHeight = window.innerHeight;
      isIE = false;
   }
}
    
function moveDiv()
{
    
   var currentLeft;
   var currentTop;
    
   if (isIE)
   {
      // IE4+ Code
      currentLeft = parseInt(floatingDiv.style.left);
      currentTop = parseInt(floatingDiv.style.top);
   }
   else
   {
      // NN4 Code
      currentLeft = parseInt(document.floatingDiv.left);
      currentTop = parseInt(document.floatingDiv.top);
   }
    
   if (currentTop < 6)
   {
      verticalMovement = Math.ceil(Math.random() * 5);
   }
   else if ( ( currentTop + floatingDivHeight) > screenHeight )
   {
      verticalMovement = -(Math.ceil(Math.random() * 5));
   }
    
   if (currentLeft < 6)
   {
      horizontalMovement = Math.ceil(Math.random() * 5);
   }
   else if ( ( currentLeft + floatingDivWidth) > screenWidth )
   {
      horizontalMovement = -(Math.ceil(Math.random() * 5));
   }
    
   currentLeft = currentLeft + horizontalMovement;
   currentTop = currentTop + verticalMovement;
    
   if (isIE)
   {
      // IE4+ Code
      floatingDiv.style.left = currentLeft;
      floatingDiv.style.top = currentTop;
   }
   else
   {
      // NN4 Code
      document.floatingDiv.left = currentLeft;
      document.floatingDiv.top = currentTop;
   }
}
    
</script>
<style>
    
   .FloatingDiv {
                 position: absolute;
                 left: 6px;
                 top: 6px;
                 width : 410px;
                 height : 260px;
                 }
</style>
    
</head>
<body onload="startTimer()">
<H3>Hello World</H3>
<div id=floatingDiv name=floatingDiv CLASS="FloatingDiv">
   <A href="WhatsNew.htm"
          onmouseover="document.FloatingImage.src = 'clickforwhatsnew.jpg'"
          onmouseout="document.FloatingImage.src = 'Welcome.jpg'">
      <img name="FloatingImage" id="FloatingImage" src="Welcome.jpg" border=0>
   </A>
</div>
    
</body>
</html>

Let's see how the page works. When the page is loaded, the window's onload event handler calls the function startTimer(). This starts a timer going at regular 100-millisecond intervals. Each time the timer fires, it calls the function moveDiv(), which moves a <div> containing our image about the page.

Let's look at the page in more detail.

Before we look at the code, we'll look at the style sheet definition in the head of the page. This defines just one style sheets class, FloatingDiv, which defines attributes that make the positioning absolute, set the left to 6 pixels, top to 6 pixels, the width as 410 pixels, and height as 260 pixels. If you use a different size image, change these values to be as large as or just slightly larger than your image. Our <div> tag that is used to hold an image and a hyperlink has this style class applied.

<div id=floatingDiv name=floatingDiv CLASS="FloatingDiv">
   <A href="WhatsNew.htm"
          onmouseover="document.FloatingImage.src = 'clickforwhatsnew.jpg'"
          onmouseout="document.FloatingImage.src = 'Welcome.jpg'">
      <img name="FloatingImage" id="FloatingImage" src="Welcome.jpg" border=0>
   </A>
</div>

Notice that we wrap our image inside an <A> tag and use its onmouseover and onmouseout events to switch the image loaded by changing the img object's src property.

Now let's look at the code. At the top of the script block we define some global, page-level variables. These are accessible from any JavaScript function on the page. The variable isIE will be populated with true or false depending on whether the browser is IE 4+. We then set two variables to hold the width and height of the Div; these will be used later for determining whether the bottom-right corner of the Div has hit the end of the screen. The variables horizontalMovement and verticalMovement contain random numbers. These are between 1 and 6 for horizontalMovement and 1 and 3 for the verticalMovement variable. These hold the amount of movement that the Div should be moved each time the timer fires. Initially the Div will be moving between 1 and 6 pixels along and between 1 and 3 pixels down the page. We'll see how this works when we look at the moveDiv() function.

var isIE;
    
var floatingDivHeight = 65;
var floatingDivWidth = 265;
var timerId;
var screenWidth;
var screenHeight;
var horizontalMovement = Math.ceil(Math.random() * 6);
var verticalMovement = Math.ceil(Math.random() * 3);
    

The function startTimer() is called by the window's onload event handler. As the name suggests, it starts a timer going at the interval of 100 milliseconds, each time calling moveDiv(). Next comes an if statement, which checks to see if document.all returns any value. If it does, this must be IE 4 or later. If this is the case we have some IE 4+ specific code that sets the screenWidth and screenHeight variables to the size of the current window, in pixels. Just before that we set the floatingDiv's left and top properties to 6. We need to do this even though we set it using a style sheet so that we can read the values later in divMove(). It's a quirk of IE that if we don't do this, reading the values will return nothing. We also set isIE to true.

The NN 4 part of the code does exactly the same thing as the IE section, except there's no need with Netscape to set style properties with code before reading them with code. Whereas clientWidth and clientHeight give us the browser window's size in IE, we need window object's innerWidth and innerHeight in Netscape. We also set isIE to false.

function startTimer()
{
   timerId = window.setInterval("moveDiv()",100);
    
   if (document.all)
   {
      floatingDiv.style.left = "6px";
      floatingDiv.style.top = "6px";
    
      screenWidth = document.body.clientWidth;
      screenHeight = document.body.clientHeight;
    
      isIE = true;
   }
   else
   {
      screenWidth = window.innerWidth;
      screenHeight = window.innerHeight;
      isIE = false;
   }
}

Finally we come to the moveDiv() function, which is called every 100 milliseconds by the timer we set going in the window onload event.

Starting from the top, our first task is to find out where on the page the Div is currently positioned. How we do this in IE differs from NN, so we need to use the isIE variable we set earlier to find out which browser this is and run the correct code. In IE the Div object's style property object's left and top properties tell us the current position. In NN we use the Layer object created implicitly for the <div> tag when we set the Div's position to absolute. It's the layer's left and top properties that provide the current position.

function moveDiv()
{
    
   var currentLeft;
   var currentTop;
    
   if (isIE)
   {
      // IE4+ Code
      currentLeft = parseInt(floatingDiv.style.left);
      currentTop = parseInt(floatingDiv.style.top);
   }
   else
   {
      // NN4 Code
      currentLeft = parseInt(document.floatingDiv.left);
      currentTop = parseInt(document.floatingDiv.top);
   }

Our next task is to work out where we should move the Div to next.

Our first if statement checks to see if the Div has reached either the top or the bottom of the page. If the top of the Div has reached the top of the page (that is, if currentTop is less than 6), we need to start the Div moving downward again. Why 6 and not 0 for the top of the page? Well, we are moving our Div in jumps of up to 5 pixels at a time. If the top is currently at position 2 and if we don't start moving downward, then the next position could be 2 – 5 making –3, which leaves part of the Div off the top of the page. If we move down when it reaches less than 6, we avoid this. The variable verticalMovement contains the number of pixels up or down a page our <div> is moved. We set this to a positive randomly selected number between 1 and 5.

If the bottom of the page has been reached by the Div's bottom, we need to start moving the Div back up the page each time the timer fires. Therefore we set verticalMovement to be a negative random number between 1 and 5. Let's say the position is currently 594 and verticalMovement is –5. The next time the timer is called, it will be 589, then 584, and so on, giving the impression of floating up the page.

   if (currentTop < 6)
   {
      verticalMovement = Math.ceil(Math.random() * 5);
   }
   else if ( ( currentTop + floatingDivHeight) > screenHeight )
   {
      verticalMovement = -(Math.ceil(Math.random() * 5));
   }

We've checked vertical movement up or down the page, so next we check to see that the Div is not at the left or right edges of the page. The principles are the same as with the vertical movement; if we're at the left, we start moving right by setting the horizontalMovement variable to a random positive number, and if at the right, we start moving left by setting horizontalMovement to a random nega-tive number.

   if (currentLeft < 6)
   {
      horizontalMovement = Math.ceil(Math.random() * 5);
   }
   else if ( ( currentLeft + floatingDivWidth) > screenWidth )
   {
      horizontalMovement = -(Math.ceil(Math.random() * 5));
   }

Finally, we calculate the required new position by adding the amount of movement needed to the current position. The variables horizontalMovement and verticalMovement either have the values allocated to them in the previous if...else statements or the random values allocated to them at the top of the page.

   currentLeft = currentLeft + horizontalMovement;
   currentTop = currentTop + verticalMovement;

Again, setting the left and top positions is different for IE and NN, so we need to use different code for each.

   if (isIE)
   {
      // IE4+ Code
      floatingDiv.style.left = currentLeft;
      floatingDiv.style.top = currentTop;
   }
   else
   {
      // NN4 Code
      document.floatingDiv.left = currentLeft;
      document.floatingDiv.top = currentTop;
   }

Team LiB
Previous Section Next Section


JavaScript Editor JavaScript Validator     JavaScript Editor


©