1. About Robby :)

My name is� Robby Wijaya, I was� born on� January 10, 1975� at� Besuki�, a� small� beatiful city. I had graduated at� Sekolah Tinggi Informatika & Komputer�� ( STIKI ) Malang on 1997. I entered this school on 1993 and got S1 grade in August 1997. I'm one of admin on Asianet IRC connection .. that's link of 25 server, and I'm also is a bawelops on Efnet IRC connection..that's link over hundred server on the world, maybe u must join with us :). I'm usualy make nick as "Stealth" or "Stealth98". If you want to contact with me , you can email me [email protected] or you can visit my page at here and sign a guestbook or you can contact my HP 081-838-8307.
2. Environment

Setting up your browser environment will help you visualize the layout and design of your web site. This is also the point where you separate the browsers that support DHTML from those that don't and trigger the page setup process.

Browser Sniffer

Let there be no confusion about browser sniffing in a cross-browser DHTML environment. I have come across many scripts that take a short cut by simply testing document.layers supported by Netscape 4.0 or document.images supported by Explorer 4.0, Netscape 4.0, and Netscape 3.0. Short cut browser sniffing is fine for simple function filtering, but in reality, the differences between the major browsers are less of a problem than the differences and bugs contained in the same browser made for multiple platforms. For this reason you will need to write a detailed browser sniffing routine to weed out not only the browser make and version but also platform, as shown in Listing 2.1.

Listing 2.1 - Detailed Browser Sniffing


function Is() {
  var agent = navigator.userAgent.toLowerCase();
  this.major = parseInt(navigator.appVersion);
  this.minor = parseFloat(navigator.appVersion);
  this.ns = ((agent.indexOf('mozilla')!=-1) && ((agent.indexOf('spoofer')==-1) && (agent.indexOf('compatible') == -1)));
  this.ns2 = (this.ns && (this.major == 3));
  this.ns3 = (this.ns && (this.major == 3));
  this.ns4b = (this.ns && (this.minor < 4.04));
  this.ns4 = (this.ns && (this.major >= 4));
  this.ie = (agent.indexOf("msie") != -1);
  this.ie3 = (this.ie && (this.major == 2));
  this.ie4 = (this.ie && (this.major >= 4));
  this.op3 = (agent.indexOf("opera") != -1);
  this.win = (agent.indexOf("win")!=-1);
  this.mac = (agent.indexOf("mac")!=-1);
  this.unix = (agent.indexOf("x11")!=-1);
}

var is = new Is();

Browser sniffing is used to separate the non-compatible browsers from those that support DHTML. Not all JavaScript methods are compatible across all DHTML supporting browsers, so some methods require separation of browser specific code. To do this, the navigator.userAgent and navigator.appVersion statements are tested to set the value of the is object. You can then test the is object for the presence of Netscape, Explorer, Opera, browser version numbers, and operating platforms. Notice that I also have a sniffing method for is.ns4b. This sniff tests for the presence of Netscape browsers older than 4.04. These browsers have a broken implementation of the important image.onload event. More info on this event and circumventing the limitation are found in the discussion on preloading images.

Resolution Detection

It is important to know the screen and window resolutions if you plan to layout your DHTML page and have it look the same across all screen resolutions. Screen resolution is the actual pixel dimension of your whole screen regardless of your browser's window size. Window resolution is the pixel dimension of your browser's open window.

When creating a new window, it is useful to know screen resolution for determining the size and position of the new window. Listing 2.3 shows how you can capture screen resolution and store it into the variables var screen_width and var screen_height for later use.

Listing 2.3 - Capturing Screen Resolution


var screen_width = screen.width;
var screen_height = screen.height;

For consistent layout of page elements across all resolutions it is important to know the actual space available within the window. Listing 2.4 shows how you can capture window resolution and store it into the variables var available_width and var available_height for later use. To maintain cross-browser compatibility, the resolution detection functions have to be placed in the <BODY> tag and triggered by an onLoad() event.

Listing 2.4 - Capturing Window Resolution


<BODY BACKGROUND="images/sky.jpg" MARGINWIDTH="0" MARGINHEIGHT="0" SCROLL="NO" onLoad="
  if(is.ns4) {
    available_width=innerWidth;
    available_height=innerHeight;
    preLoad();
  } else if(is.ie4) {
    available_width=document.body.clientWidth;
    preLoad();
  }"
onResize="history.go(0)">

The value of the is.ns4 object is determined by the Browser Sniffer method. If the is.ns4 object is true, then Netscape�s innerWidth and innerHeight window resolution detection methods are used. If the is.ie4 variable is true, then Explorer�s document.body.clientWidth and document.body.clientHeight window resolution detection methods are used. The variables available_width and available_height will store the horizontal and vertical window dimensions. These values are used later to position style sheet elements.

After the window resolution variables have been set the preLoad() function is initiated to preload images and trigger the rest of the document setup process.

To ensure that the layers get repositioned when the window is resized, the onResize="history.go(0)" statement is incorporated to catch a window resize event and reloads the page from the browser�s cache. The MARGINWIDTH="0", MARGINHEIGHT="0", and SCROLL="NO" attributes are places in the <BODY> tag to keep the default scrolling bars from appearing after the page has been resized.

Window Control

One consideration to make when setting up your DHTML environment, is to determine how the page will be displayed. Options include building frames, using the existing window, or creating a new window. The main advantage of creating a new window is having complete control of window size and position. Listing 2.5 show the code for creating a new window using screen resolution for determining the window's position.

Listing 2.5 - Creating & Positioning Windows


function openWindow() {
  if(is.ns4 || is.ie4") {

    var window_left = (screen.width-640)/2;
    var window_top = (screen.height-480)/2;

    window.open('curious_eye.htm','curiousEye',
'width=640,height=480,top=' + window_top + ',left=' + window_left + '');
  }
}

The first step in creating a new window for a DHTML site is to test the is variable for the presence of a compatible browser. The next step is to set up the window position variables window_left and window_top using screen resolution information. Since the goal is to center a 640 x 480 window in the middle of the screen, the window size is subtracted from the screen resolution and divide by 2.

Next the window.open() function is built using the position variables for the top and left attributes. Additional window parameters and attributes are available, but not listed here.

Linking External Files

You have the option of including all the style sheet definitions and JavaScript code directly on the page containing HTML. With the complexity of DHTML, you may find it easier to manage these files separately as external links. Listing 2.6 illustrates how to link external Style Sheet and JavaScript files. These links are placed within the <HEAD></HEAD> tags of the HTML page.

Listing 2.6 - Linking Files


<SCRIPT LANGUAGE="JavaScript" SRC="script.js"></SCRIPT>

<LINK REL=stylesheet TYPE="text/css" HREF="styles.css" TITLE="style">

Linking to external files doesn't prevent you from adding small scripts and mouse events to the HTML page.

3. Graphics

There are graphic development techniques that are specific to DHTML development. These techniques generally exploit the nature of transparent GIF images and the ability to overlap layers.

Screens

Screened images can add a unique effect to a DHTML web site by giving the feel of translucency and depth especially if there are objects placed behind the screen.

In Photoshop, creating a screen is achieved by deleting every other pixel of a solid color in a small square image. Using the Select Tool, select the entire square and choose Define As Pattern option. You can then apply the screened pattern to any shape you create the with Marquee Tool. For the menu, I created a solid purple screen and applied it as a pattern to the rounded menu box shape. From there, the edges of the selected box shape is airbrushed with a lighter color for highlights. The screen image is saved as a transparent GIF. Screens can float above the background in their own layer or as an attribute of a table element as shown here.

<TABLE BACKGROUND="menu_screen.gif">

Composite Images

The animated eye is an example of a composite image made up of four overlapping layers. Composite images open a world of possibilities as you can add animation techniques to each layer allowing fully independent movement.

Building composite images are best suited for graphic applications that support layering, such as Photoshop 4.0 or a 3-D program like TrueSpace3. The model for the eye and carriage was built in TrueSpace3 using simple sphere and cylinder primitives. Animation of the eyeball was achieved by turning the visibility of the eyelid and carriage objects off, then the eye was rotated to a new compass position where it was rendered as a single frame. By applying the same process to the eyelid and carriage objects, I was able to build separate images for each animated part of the eye. All eye graphics were opened in Photoshop and saved as a GIF with transparent backgrounds.

4. Layers

Layers are the basic building blocks allowing you to overlap and position text and graphics anywhere you want. Unlike the <LAYER> tag specific to Netscape, this tutorial uses style sheet layers to maintain cross-browser compatibility.

Style Sheet Layer Construction

A general style sheet layer consists of the opening <DIV> tag with the attributes of ID="" and STYLE="". Within the layer, you can place standard HTML content as well as scripts, plugins, applets and controls. The layer is then closed using the end </DIV> tag, as shown in Listing 4.1.

Listing 4.1 - General Style Sheet Layer Construction


<DIV ID="layerName" STYLE="position: absolute; top: 10px; left 10px; width: 100px; height: 100px; clip: rect(0 100 50 0); z-index: 2; visibility: hidden;">

<FONT CLASS="MAIN">Standard HTML text, images and links</FONT>

</DIV>


The ID attribute is the unique identification of the layer. Generally it follows the naming convention of [lowercaseUppercase] as in, ID="myLayer". The layer ID can be referenced in JavaScript when dynamically changing the layer's attributes.

The STYLE attributes contain the physical properties of the layer such as its position, width, height and visibility.

The position: absolute; attribute defines the layer's coordinates relative to the screen given that the coordinates of the upper left corner of the browser window is 0 pixels left by 0 pixels top. Layers can also be nested within each other in which the position attribute of the nested layer is set to relative.

The top: 10px; attribute vertically positions the layer's top edge. In this example it is positioned ten pixels down from the top edge of the browser window [px refers to pixels].

The left: 10px; attribute horizontally positions the layer's left edge. In this example it is positioned ten pixels right from the left edge of the browser window.

The width: 100px; attribute defines the width of the layer. In this example it is defined as 100 pixels wide.

The height: 100px; attribute defines the height of the layer. In this example it is defined as 100 pixels high.

The clip: rect(0 100 50 0); attribute defines the clipping box around the layer using the boundaries of rect(Top, Right, Bottom, Left). A clipping box restricts the visible area of the layer within its own dimensions. Only the portion within the clipping box will be visible. In this example the Top boundary is set to 0 pixels, the Right boundary is set to 100 pixels, the Bottom boundary is set to 50 pixels, and the Left boundary is set to 0 pixels. Since the layer is defined as a box a 100 pixel wide by a 100 pixel high, only half of the layer will show when using this clipping box.

The z-index: 2; attribute defines the overlapping stacking order of layers. A z-index of 1 indicates that the layer is lowest in the stack. You can position a second layer over the first by giving it a z-index of 2.

The visibility: "hidden"; attribute either hides or displays the layer to the browser. Layers with the visibility attribute of "hidden" cant be seen, while layers with the visibility of "visible" can. The visibility attribute as with most of the layer attributes can be manipulated directly by JavaScript.

Dynamic Layer Construction

The layers used in this tutorial are slightly different because of their dynamic nature. As shown in Listing 4.2, a dynamically controlled layer can be simplified in which the attributes are controlled through JavaScript. In this tutorial, layer visibility is initially set to hidden. As the page is loaded, JavaScript is used to dynamically position the layers based on screen resolution, then the layer's visibility is turned on.

Listing 4.2 - Dynamic Style Sheet Layer Construction


<DIV ID="sphere1Lyr" STYLE="position: absolute; width: 102px; height: 102px; z-index: 9; visibility: hidden;">
  <IMG NAME="sphere1_image" SRC="images/sphere1.gif" WIDTH="102" HEIGHT="102" BORDER="0">
</DIV>

Font Control

A style sheet can precisely control font type, size, style and color. The benefit of using style sheets include the ability to make a single change to font attributes which will be reflected in all pages of the web site. Listing 4.3 shows the font definition for the main body text for this web site.

Listing 4.3 - Style Sheet Font Definition


.MAIN {
  font-size: 10pt;
  font-weight: 100;
  color: #DDDDBB;
  font-family: "verdana", "arial", "helvetica", sans-serif;
}

To apply this font definition to the HTML text you can wrap the HTML text with a font tag specifying the style sheet definition name, such as <FONT CLASS=MAIN>Style Sheet Font Control</FONT>

In addition to specifying your own definition names, you can alter the default setting to standard HTML tags such as the <B> tag as shown in Listing 4.4.

Listing 4.4 - Style Sheet HTML Tag Definition


B {
  font-size: 9pt;
  font-weight: 100;
  font-family: "Courier New", "arial", "helvetica", sans-serif;
  color: #FFFFFF;
}

With the bold style sheet element defined, any >B> tag will take on the defined style. The style sheet attributes listed here are just a fraction of what is available, so a good style sheet reference is necessary.

5. DOMS

To make the Dynamic HTML code compatible in both Netscape & Explorer, a Document Object Model Script (DOMS) is used. Figure 5.1. is the script used to assign browser specific variables, doc, sty, and htm depending on the visiting browser. The variables are then used later to build cross-browser JavaScript methods - saving the hideous step of writing code separately for each browser.

Listing 5.1 - DOMS Switch


if(is.ns4) {
  doc = "document";
  sty = "";
  htm = ".document"
} else if(is.ie4) {
  doc = "document.all";
  sty = ".style";
  htm = ""
}

The is object variable is tested for Netscape 4.0 with the is.ns4 statement. If the is object returns true, then three Document Object Switch variables are set for Netscape. The is object variable is also tested for Explorer 4.0 with the is.ie4 statement. If the is object returns true, then the three Document Object Switch variables are set for Explorer. The doc variable is used to determine how the two different browsers refer to document objects. Netscape uses the document.object statement, while Explorer uses the document.all.object statement. The sty variable is used to determine how the two different browsers refer to style sheet objects. Netscape uses the document.style_name.object statement, while Explorer uses the document.all.style_name.style.object statement. The htm variable is used to determine how the two different browsers refer to HTML objects within a style sheet layer. Netscape uses the document.style_name.document.object statement, while Explorer uses the document.all.style_name.style.object statement.

6. Preloading

To achieve real-time animation with DHTML, it is necessary to preload the images into browser memory. This is done through image preloading methods as shown in Listing 6.1. Once loaded into memory the images can be controlled programmatically to produce animations.

Listing 6.1 - Preloading Image Manager


var count = 0;

function preLoad() {
  sphere1 = new Image();
  sphere1.onload = (is.ns4b) ? loadCheck() : loadCheck;
  sphere1.src = "sphere1.gif";

  sphere2 = new Image();
  sphere2.onload = (is.ns4b) ? loadCheck() : loadCheck;
  sphere2.src = "sphere2.gif";
}

function loadCheck() {
  count++;
  if(count == 2) {
    positionLayers();
  }
}

The preLoad() function is initiated by the onLoad() event handler contained in the <BODY> tag as shown here.

<BODY onLoad="preLoad()">

The first step of the preload() function is to create an image object and assign it to a variable with the imageName = new Image() statement.

To determine if the image object is being loaded, the image event handler, imageName.onload = loadCheck is used to trigger the loadCheck() function every time an image is being loaded. Note: Strangely enough the onload event has to occur before the image is actually assigned to the image object. The onload event must also be in lowercase to maintain browser compatibility. In addition, the reference to the function loadCheck must be referred to with out the parentheses (), because the function is being called from an event that normally resides as an attribute of the <IMG> onload="loadCheck()" tag where it would contain the parentheses.

Bug Workaround: In this example, the browser sniffer value of is.ns4b is used to test for the presence of Netscape versions 4.01 through 4.03. These browsers do not implement the image.onload event correctly. If is.ns4b returns true, then the loadCheck() is used which doesnt really do anything. If is.ns4b returns false, then the correct loadCheck method is called.

Once the image object is created, an image URL is assigned to the object's .src attribute with the imageName.src = "imageURL.gif" statement.

The loadCheck() function simply increments count variable with count++, then tests the variable against the number of images expected to load with the if(count == 2) statement. Once the image count has been reached, other functions can be triggered to position the layers.

7. Positioning

Initially we created the dynamic style sheet layers without defining the layer's left and top position attributes, and the layer's visibility attribute was set to hidden. Now that the images have been loaded, we can use the methods in Listing 7.1 to create layer objects, dynamically position the layers, and finally make them visible.

Listing 7.1 - Positioning Layers


function positionLayers() {
  sphere1Img = eval(doc + '["sphere1Lyr"]' + '.document');
  sphere1Obj = eval(doc + '["sphere1Lyr"]' + sty);
  sphere1Obj.left = 7;
  sphere1Obj.top = available_height-230;

  sphere2Img = eval(doc + '["sphere2Lyr"]' + '.document');
  sphere2Obj = eval(doc + '["sphere2Lyr"]' + sty);
  sphere2Obj.left = parseInt(sphere1Obj.left) + 40;
  sphere2Obj.top = parseInt(sphere1Obj.top) + 74;

  sphere1Obj.visibility = "visible";
  sphere2Obj.visibility = "visible";

  animate();
}

Creating Layer Objects

The first step of the positionLayers() function is to define two types of document layer objects using the DOMS variables set earlier. The first type is an image layer object which is used to access the properties of an image placed within a layer and is defined as:

sphere1Img = eval(doc + '["sphere1Lyr"]' + '.document');

Recall that doc is a DOMS variable that handles the different ways Netscape & Explorer refer to any document object within a DHTML page. The name "sphere1Lyr" is the layer's ID attribute. Once built, the image layer object is assigned to the variable sphere1Img and is used later for dynamic image control within a layer.

The second type of layer object is used for directly accessing layer properties and can be built with the DOMS variables in the following manner:

sphere1Obj = eval(doc + '["sphere1Lyr"]' + sty);

Recall that sty is a DOMS variable that handles the different ways Netscape & Explorer refer to any object within a style sheet layer. Once built, the layer object is assigned to the variable sphere1Obj, which is used later for dynamically manipulating the layer's attributes.

Manipulating Layer Position

Using the layer objects defined above, you can dynamically change the left and top position attributes of the layer as illustrated in Listing 7.2.

Listing 7.2 - Dynamic Positioning


sphere2Obj.left = 7;
sphere2Obj.top = available_height-200;
sphere1Obj.left = parseInt(sphere2Obj.left) + 40;
sphere1Obj.top = parseInt(sphere2Obj.top) + 74;

Notice that the top attribute of the sphere2Obj is positioned using the available_height-200 statement, and the sphere1Obj.left attribute is positioned using the coordinates of the sphere2Obj object plus 40 pixels. This shows how you can position objects relative to each other or relative to the window resolution. The parseInt() wrapper around the layer objects is used to strip out any string characters, such as, "px" (pixels) for cross-browser compatibility.

Manipulating Layer Visibility

As illustrated in Listing 7.3, you can dynamically toggle a layer's visibility attributes on "visible" and off "hidden".

Listing 7.3 - Dynamic Visibility


sphere1Obj.visibility = "visible";
sphere1Obj.visibility = "hidden";
sphere2Obj.visibility = "visible";
sphere2Obj.visibility = "hidden";

Manipulating Layer Z-index

As illustrated in Listing 7.4, you can dynamically assign a layer's z-index attribute to any specific order.

Listing 7.4 - Dynamic Z-index Ordering


sphere1Obj.zIndex=11;
sphere1Obj.zIndex=9;

Once layers have been positioned and made visible, you can trigger other functions to perform animation.

8. Animation

Layer animation and image animation are the two basic types of animation techniques used in this tutorial. Although they are independent animations techniques, they can be combined together to produce complex animated effects as demonstrated by the roaming eye.

Layer Animation

Layer animation is the process of moving the layer's left or top position attributes in a recursive loop as shown in Listing 8.1.

Listing 8.1 - Layer Animation


function animateLayers() {
  var x_pos1 = parseInt(sphere1Obj.left);
  var x_pos2 = parseInt(sphere2Obj.left);
  if(x_pos1 < 47) {
    sphere1Obj.left = x_pos1+2;
    sphere2Obj.left = x_pos2-2;
    setTimeout("animateLayers()", 1);
  }
}

The first step of this animation method is to store the layer's current left position into a variable with the var x_pos1 = parseInt(sphere1Obj.left); statement. The parseInt() wrapper converts the layer's left coordinates into a number to maintain cross-browser compatibility. Since we are moving two objects in this example, the current position of the second object is stored into the x_pos2 variable.

We can now compare the layer's current location to the location where we want it to stop, using the if(x_pos1 < 47) statement. As long as the x_pos1 variable is less than 47 pixels, the methods within the if statement will be executed.

The next portion of the function actually moves the layer by assigning a new position to the layer's left attribute with the sphere1Obj.left = x_pos1+2 statement. This statement will change the layer's left position +2 pixel to the right. You can control the distance and direction the layer can be moved by adding or subtracting the number to the layer's current position.

The setTimout() function is used to recursively call the animateLayers() function at a delay rate of every 1 millisecond. You can speed up or slow down the looping speed by changing the loop delay. The animateLayers() function will continue to loop until the layer's current left position becomes greater than 47 pixels.

Image Animation

Image animation is the process of dynamically replacing an image with a preloaded image. Listing 8.2 shows the animation technique for replacing one image with another in a recursive loop.

Listing 8.2 - Dynamic Image Replacement


var counter = 0;

function animateImage() {
  if(counter < 10) {
    sphere1Img.sphere1_image.src = sphere2.src;
    setTimeout("sphere1Img.sphere1_image.src=sphere1.src", 500);
    setTimeout("animateImage()", 1000);
    counter++;
  } else {
    counter = 0;
  }
}

Recall that the sphere1Img object variable has been defined earlier in the Positioning section. This image layer object will allow Netscape and Explorer to change the source of the image to one that has been preloaded with the sphere1Img.sphere1_image.src = sphere2.src; statement. You can control the number of loops the animation goes through by using a counter variable. For each loop cycle, the counter variable is incremented by one using the counter++ statement. Once the counter reaches 10, the else branch is triggered which resets the counter to 0.

Random Image Animation

The curious eye example uses random image animation to give the eye a bit of personality. This technique randomly selects a image stored in a data array then dynamically replaces images in a timed sequence. Listing 8.3 shows the sample code for setting up a data array to store the names of preloaded images, then use a random selector routine to animate the image.

Listing 8.3 - Random Image Animator


var sphereArray = new Array()
sphereArray[0]="sphere1";
sphereArray[1]="sphere2";

function randomImage() {
  if(counter < 10) {
    sphere1Img.sphere1_image.src = eval(sphereArray[Math.round((sphereArray.length-1)*Math.random())] + ".src");
    sphere2Img.sphere2_image.src = eval(sphereArray[Math.round((sphereArray.length-1)*Math.random())] + ".src");
    setTimeout("randomImage()", 1000);
    counter++;
  } else {
    counter = 0;
  }
}

The first step in building a data array is to create an array object with the var sphereArray = new Array() statement. Once the array object has been defined, it can then populated with the names of preloaded images. (It is programming convention to start an array index with [0], but count it as 1.)

The next step is to randomly select an image name from the data array using the eval(sphereArray[Math.round((sphereArray.length-1)*Math.random())] + ".src"); statement. The first process of this statement is to calculate a random value between the first and last index value of our image data array by multiplying the sphereArray.length-1 by the Math.random() function. The sphereArray.length property returns the number of data elements in the array. The number 1 is subtracted from the array length property to account for the index value of the array starting with zero. The resulting calculation is then rounded with the Math.round() function to preserve whole numbers. The resulting random number from the image array is inserted into the evaluation statement eval() that converts the image name based on the index value of the imageArray into the name of the preloaded image object.

The same process is used to randomly replacing the second image object. As with the previous image replacement function, the images are continuously replaced in a recursive loop until the counter variable reaches 10.

9. Interactivity

Dynamic HTML offers increased freedom in crafting an interactive environment that can include page scrolling, page selection, and other navigational methods.

For this site, all text is stored in hidden layers on the same page, so there is a need for managing layer display. The function in Listing 9.1 is responsible for toggling on the visibility attribute of a selected layer and turning off the visibility attribute of a previously selected layer.

Listing 9.1 - Page Selection


var menu_selection = "overview";

function menuToggle(selection) {
  var old_page = eval(menu_selection + "Obj");
  old_page.visibility = "hidden";

  var new_page = eval(selection + "Obj");
  new_page.visibility = "visible";

  menu_selection = selection;
}

When a menu item is clicked, it passes the name of the layer it represents to the menuToggle(selection) function. The first step of this function is to build the old_page object variable using the name stored in the menu_selection variable. The old_page visibility attribute is then made "hidden" with the old_page.visibility = "hidden"; statement.

The next step is to build the new_page object variable which will store the name of the selected layer. The new_page visibility attribute is then made "visible" with the new_page.visibility = "visible"; statement.

The menu_selection variable is then updated with the name of the selected page, so the next time around, the currently displayed layer will be hidden.

Capturing Image Map Events

Image maps take on a new life in DHTML documents by providing an easy way to capture mouse events in a defined area. Listing 9.2 shows one of seven hotspots used for the scrolling arrow interface.

Listing 9.2 - Image Map Events


<MAP NAME="arrows_map">
  <AREA SHAPE=RECT COORDS="0,0,36,28" HREF="JavaScript://" onMouseOver="loop=true;scroll('up',1)"; onMouseOut="loop=false;clearTimeout(timer1)" ALT="Slow Scroll">
</MAP>

To achieve multiple scrolling speeds, each hotspot defined in the image map passes direction, speed, and loop control information to the page scrolling function using the onClick, onMouseOver and onMouseOut events.

An image map can be extended by linking to a blank GIF image that has been sized in a layer to fit over the entire screen or just a small part.

Page Scrolling

Standard window scrollbars become useless when developing a DHTML site with independent layers. For this reason it becomes necessary to create your own scrolling mechanism. Listing 9.1 shows the code for scrolling the content layer using the onMouseOver image map events defined earlier.

Listing 9.3 - Scrolling Pages


var loop = true;
var direction = "up";
var speed = 10;
var timer1 = null;

function scroll(dir,spd) {
  direction = dir;
  speed = spd;
  var page = eval(menu_selection + "Obj");
  var y_pos = parseInt(page.top);
  if(loop == true) {
    if(direction == "dn") {
      page.top = (y_pos-(speed));
    } else if(direction == "up" && y_pos < 10) {
      page.top = (y_pos+(speed));
    } else if(direction == "top") {
      page.top = 10;
    }
    timer1 = setTimeout("scroll(direction,speed)", 2);
  }
}

A simple form of the scrolling function could be limited to just moving the layer every time a button is clicked. A slicker method is to add animation methods to automate the scrolling of the layer. The scroll(dir,spd) function is initiated by one of seven onMouseOver image map events which passes two variables containing direction and speed information to the function. This information is stored into global variables direction and speed which are used repeatedly when the animation function is put through a loop.

The next step in the function is to build the name of the layer object using the name stored in the menu_selection global variable set earlier. Once the name of the object is known, the parseInt(page.top); statement is used to capture the layer's current position and store it in the y_pos variable.

The idea behind the scrolling mechanism is to keep the page scrolling as long as the mouse is over an arrow. To do this, it is necessary to track of the status of the loop variable. As long as the loop variable is true, the page will scroll. The loop variable is toggled between true and false with the onMouseOver and onMouseOut image map events.

The next step is to use a series of if...else statements to test the direction variable for which direction the page should be traveling. As in the layer animation methods discussed earlier, the currently selected layer is then moved by adding or subtracting the speed variable from the layer's current position and then assigned to the layer's .top position attribute. The layer is continuously repositioned at the same speed with a looping function until a new speed and direction command is initiated.

A timing loop conflict exists when you call a looping function repeatedly before allowing the timed event to expire. To prevent this, the setTimeout() function is stored in the timer1 variable. The timer can then be canceled with the clearTimeout(timer1) method when the mouse moves from one image map hotspot to another.

1. About Me
2. My Material
3. My GuestBook
4. My Friends
5. DOMS
6. Preloading
7. Positioning
8. Animation
9. Interactivity
Slow Speed Medium Speed Fast Speed Return To Top Fast Speed Medium Speed Slow Speed