Creating DHTML Applications - (6/8) | WebReference

Creating DHTML Applications - (6/8)

To page 1To page 2To page 3To page 3aTo page 3bcurrent pageTo page 4aTo page 5

Creating DHTML Applications

Case Study

To see how this methodology works in 'real life,' let's look at a case study. The objective is to develop animated menus, and in our example we will have 4 menus, and 4 descriptions, of variable heights.

BEHAVIOR scripting

What exactly do we want to do?

We want to design a display-system with 4 menus. If one of the menus is rolled-over, the description of that menu will become visible. To do that, all the underlying menus will have to move down to make space for the menu's description. Before all that happens, the menus need to 'collapse' to the initial state, in case a description was already shown.

Have a look at the following example: menu system (opens in a new window).

To summarize, on mouseover:

We also want to make this application flexible, so that functionality can be extended in the future.

In the initial html document we create 2 times 4 layers (4 menus and 4 descriptions). We give the layers (divs in this case) the style 'menu' that makes the positioning absolute (so we can reposition it later), and make it invisible.

I chose an Object Oriented approach, therefore we create an object called 'menus,' with 3 initial properties:

function menus(objID,tMenu,sMenu) {
   this.objID = objID;//ID
   this.elID = "tMenu" + objID;//name of menu layer
   this.subElID = "sMenu" + objID;//name of description layer

We create the objects when the page loads, and store them in an Array called menuA.

We overlooked one thing in the initial business logic: when the page loads initially, we will have to display each of the menus. Therefore we need to do two things:

  1. measure the height of each layer (so that we know where to position the following)
  2. display all the menus.

Therefore we add two methods, and the needed properties, to the object:

function measure() {
   //measure menus and description and put in array
   tMenuH[this.objID] = measureHeight(this.elID);
   sMenuH[this.objID] = measureHeight(this.subElID);
function showMenu() {//this method will show the menus
   //Start form the top:
   //Then go through all the menus that are there, 
   //to find the position of the next one:
   for (var i=0;i<=this.objID-1;i++) {
      posY += parseInt(tMenuH[i]) +;//add the gap
   this.posY = posY;//make the object 'remember' where the menu is
   makeVis(this.elID,this.posX,posY);//position it and make visible

Let's look at what we have at this stage:

Example (opens in new window)

Now for the exciting bit, introducing the movement.

First, we need to evoke a function when rolling over the menus:

function openMenu(id){//opens a menu-description
   //loop through menus and close all descriptions 
   //and repositioning the menus
   for (var i=0;i<menuA.length;i++) {

This is using the rePos() method, which is using other methods to 'manage' the animation:

function rePos(id) {
   //first make the description invisible in case it was showing
   //find the final Y pos where the menu is moving to
   for (var i=0;i<=this.objID-1;i++) {//loop through all previous
      posY += parseInt(tMenuH[i]) +;
   //we check if it is the last menu
   //if it is, then we create a new method that will show 
   //the selected description after all menus have animated down:
   if (this.objID == tMenuH.length-1) {
      var  f="openSub(" + id + ")";//open the subnav
   } else {//otherwise wait with opening
      var  f="";//empty method
   this.finish = new Function(f);//-> created the new method
   //animate the menu down to posY, in steps of -10px:

As you can see, new methods are created as needed, and the final result is this:

Final result (opens in new window)


To page 1To page 2To page 3To page 3aTo page 3bcurrent pageTo page 4aTo page 5

Created: July 23, 2001
Revised: July 23, 2001