Tutorial 6 - DOM & DHTML

Tutorial 5 - Forms and DHTML - Tutorial 7 - Animation

The W3 Consortium document object model (DOM) that is implemented in all modern browsers extends access to virtually every HTML element using programming objects as the basic modeling paradigm. This allows a variety of scripting languages to dynamically modify the look of a page as they react to events. Although all modern browsers incorporate DOM, they are not at the same stage and the model itself is being extended. QuirksMode.com gives details of variants. It is a wise procedure to test any browser that your clients/viewers may use against the w3.org dom support test.

Accessing an Element Using DOM

The usual procedure for setting up access to an element is:

  1. Establish appropriate property values for the element's class.[CSS]
  2. Identify the element with a unique id attribute.[HTML]
  3. Set a class group attribute for the element.[HTML]
  4. Create an activating event that passes the identifier [HTML]
  5. Capture the element's style object.[script]
  6. Work with the element's style, position, visibility or content[script]

Capturing the element's object uses the DOM document.getElementById('idname') method and the appropriate object such as style. You can then modify any of the object's properties (such as style, position, visibility or content).

Dynamic Style - Color Changes and Fades

Objects and Events has already demonstrated how different images could be activated with the onMouseOver and onMouseOut events. As an simple example of implementing DHTML using the DOM model here is one approach for changing a heading's color as the cursor rolls over it. Note that the element identifier is passed to JavaScript so that the function can be written in a generic way.

This is the changing color heading...

...
<style type="text/css">
h2.rollover {color:black}  /* initialize properties on class */
</style>
<script type="text/javascript">
function change(thistag) {
   styleObj=document.getElementById(thistag).style;
   styleObj.color="red";
}
function back(thistag) {
   styleObj=document.getElementById(thistag).style;
   styleObj.color="black";
}
</script>
...
<h2 id="roll" class="rollover"
   onMouseOver="change('roll');" onMouseOut="back('roll');">
This is the changing color heading...</h2>
...

You can achieve a fade effect by choosing colors of successive shades and cycling through them. Our first example of fade is programmed with a increment function using a switch statement to select the next color. The onMouseOver event is used to trigger the event. You could also use an onclick event or better still an onLoad event and setTimeout() method.

Stroke Me!

The JavaScript code for the fade function is:

fadept=0; // global to remember fade state
function fade(thisone) {
col="#000";
switch (fadept) {
    case 0:col='#000';break;
    case 1:col='#333';break;
    case 2:col='#666';break;
    case 3:col='#999';break;
    case 4:col='#aaa';break;
    case 5:col='#ccc';break;
    case 6:col='#ddd';break;
    case 7:col='#eee';break;
    case 8:col='#fff';break;
    }
fadept += 1;   // increment for next time around
if (fadept>8) {fadept=0;}  // hit end so reset
    styleObj=document.getElementById(thisone).style;
    styleObj.color=col;
 }

The second version of fade uses a mathematical progression for the fadeout. It also automatically fades on a timer. You may want to reset the count or have a method for starting the fade another time.

fadept2=0;       // global to remember fade state
fadeid="fadezone"; // global for object to be faded
function fade2() {
    if (fadept2 < 255) {
    fadept2+=4;
    styleObj=document.getElementById(thisone).style;
    newColor= 'rgb('+fadept2+','+fadept2+','+fadept2+')';
    styleObj.color=newColor;
    setTimeout('fade2()',2);
    }
}

For a more flexible fader check the source code for JR's Ultimate Fader. The user can pick both start and finish color as well as the number of steps in the fade effect. Routines to allow cycling or reverse cycling are included but not hardwired. The effect can also be redirected to any element that a programmer wishes to write for.

Dynamic Style - Fontsize Changes and Zooms

Instead of using color changes, you could do fontsize changes to achieve a zooming effect. Instead of using the switch to set the colors, you set siz="12pt"; etc. and then use the fontSize property. Note that style properties with hyphens are changed when used as a JavaScript property. Drop the hyphen and capitalize the next word such as margin-left becomes marginLeft.

Touch Me!

Dynamic Positioning - Floating GoToTop Link

Longer pages cause problems for some viewers. A GoToTop link sitting in the lower right of the screen can help. This sticky element technique can be done by making the element move according to its scrolled position. A loop monitors the visual top of the document and adds an offset to place the element at the bottom of the screen. The same type of process can be used to hold menus on the screen.

/* shield page from geezer browsers -- try to get them to upgrade */
if (document.layers) {top.location.href="http://www.mozilla.org";}
if (document.all &amp; !document.getElementById) { //oops - MSIE ver 5
   top.location.href="http://www.microsoft.com/windows/ie/";}
scrollSpeed2=20;    //Screen refresh rate in msec.?
scrolled2='document.body.scrollTop';var ltop2;
function checkScrolled2(){ //backTo Top link stays in lower right
   document.getElementById('backZone').style.top=eval(scrolled2)+ltop2+'px';
   setTimeout('checkScrolled2()',scrollSpeed2) ;}
function writeBack() { copy =''; // write backToTop link dynamically
   copy+='<a class="backZone" href="#top">GoTo Top<\/a>';
   document.getElementById('backZone').innerHTML=copy;
   x1=eval(scrolled2);window.scrollBy(0,1);  //test scrolled2 ptr
   x2=eval(scrolled2);window.scrollBy(0,-1); //reset position
   if ((x2-x1)<1) {scrolled2='document.documentElement.scrollTop';}
   ltop2=parseInt(document.getElementById('backZone').style.top);
   checkScrolled2();}

An onload to the initiating writeBack() function is required. The link class (backZone) can be styled if desired. The element with the backZone id must be added to the body as in:

<div class="backZone" id="backZone"
style="position:absolute;top:380px;left:655px;z-index:3"></div>

The start of the script checks for conformant browsers and points at the object that normally contains the document scrolled info. The initializing function (writeBack) alters that pointer for browsers that do not use that method. On scrolling the top property is adjusted to hold position. A further improvement would be to adjust both top and left offset to accomodate resolution changes and window sizing.

Dynamic Visibility - Collapsing Text

Using the display property of CSS, one can hide segments of content such as detailed descriptions or sub topics until needed. This adds clarity to the presentation. Collapsing menus is another application of the visibility concept. The function expand uses a pointer from the topic element clicked on to access and unhide its related subtopic element. The next click on the topic element rehides the subtopic. This could be expanded several levels if needed.

Topic One
Topic Two
Topic Three

The HTML component uses topic tags (in this case address, it could have been a heading tag) that are always visible but clickable. The onclick event calls the expand function for its related subtopic element.

<address onclick="expand('text1');">Topic One</address>
<p id="text1" style="display:none;color:red">
A whole bunch of stuff that needs display</p>
....  etc.

The expand function toggles the visibility property for any referenced element. Note that a global state saver is not needed as this function can easily access the current state using a style property.

function expand(thistag) {
   styleObj=document.getElementById(thistag).style;
   if (styleObj.display=='none') {styleObj.display='';}
   else {styleObj.display='none';}
}

Dynamic Content - Toggle Button Example

To dynamically change content of a document element you do not use its style object. You use the innerHTML property (note case carefully!) An example is document.getElementById('tag').innerHTML='whatever';

One very important use of dynamic content is to isolate repetitive or changing text to an external JavaScript file. All documents needing this material only require a pointer to the file and a specific element to contain it. Any change in the content need not be copied to all referring documents.

Some utilities need a push to start/push to stop or toggle button. One example is a run/pause button within a slide show. Since a button's value is normally displayed as a caption, it becomes easy to alter the caption with an if condition. In the following code fragment the toggle function rewrites the innerHTML.

flip="Start"; // global to save state
function toggle() {
if (flip == "Start") {
   flip="Stop";
   //insert start code here
   copy ='<input name="b" type="button" value="Stop" ';
   copy+='class="zone" onclick="toggle();">';
   document.getElementById('togglezone').innerHTML=copy;
   } else {
   flip="Start";
    //insert stop code here
   copy ='<input name="b" type="button" value="Start" ';
   copy+='class="zone" onclick="toggle();">';
   document.getElementById('togglezone').innerHTML=copy;
    }
}

Tutorial 5 - Forms and DHTML - Tutorial 7 - Animation

Copyright (c) 2005 by John W. M. Russell