Creating DHTML Applications - (4/8) | WebReference

Creating DHTML Applications - (4/8)

To page 1To page 2To page 3current pageTo page 3bTo page 4To page 4aTo page 5
[previous][next]

Creating DHTML Applications

PROPERTY scripting

Now that we know how to refer to a certain object in our target browsers, we can concentrate on how to change the properties of that object.

In the following example, we want to change the source of the image (myImage2), located in the layer (mainLayer).

Example (opens in new window)

Traditionally the following syntax would be used:

if(document.layers) {
   document.layers['mainLayer'].document.images.myImage2.src = "shades2.gif";
} else if (document.all) {
   document.all.myImage2.src = "shades2.gif";
} else {
   document.getElementById('myImage2').src = "shades2.gif";
}

As you can see, all of the conditions are the same except for the DOM reference. Therefore, we can reduce the code to this:

mElement('myImage2','mainLayer', 'iMageZ').src = "shades2.gif";

In this case there are no exceptions at all.

Unfortunately, browser manufacturers have not made it that easy for all tasks and often we have to make exceptions. If, in our example, we want to move the layer (mainLayer) to 475px from the left, and 35px from the top, we can write the following function:

function moveLayer() {
   if(document.layers) {//exception to the standard
      document.layers['mainLayer'].moveTo(475,35);
      //alternatively we could use:
      //mElement('mainLayer').moveTo(475,35);
   } else {//standard
      mElement('mainLayer').style.left = 475;
      mElement('mainLayer').style.top = 35;
   }
}

However, it would not be good practice to write the function the above way. We should pass the layer name and the coordinates, as arguments of the moveLayer function, so that we can store the function in our library in order to reuse it later:

function moveLayer(divName,posX,posY) {
   if(document.layers) {//exception to the standard
      document.layers[divName].moveTo(posX,posY);
   } else {//standard
      mElement(divName).style.left = posX;
      mElement(divName).style.top = posY;
   }
}

Note that the 'style.left/top' syntax in the example is, theoretically, not correct. I should add a unit to the 'mElement(divName).style.left = posX' syntax: mElement(divName).style.left = posX + "px" for example. Or I should use MSIE's pixelLeft property. I found that the syntax I use here works fine in all browsers, but this is a typical example of how a property function could easily be updated, or even 'upgraded.' If I had found out, for example, that this syntax is not accurate enough in a particular browser, I could edit it like this:

function moveLayer(divName,posX,posY) {
   if(document.layers) {//exception to the standard
      document.layers[divName].moveTo(posX,posY);
   } else if (document.all) {//old MSIE
      mElement(divName).style.pixelLeft = posX;
      mElement(divName).style.pixelTop = posY;
   } else {//DOM browsers
      mElement(divName).style.left = posX + "px";
      mElement(divName).style.top = posY + "px";
   }
}

This is just an example of how a 'PROPERTY function' can be extended and still be backward compatible.

In some cases it is necessary to retrieve the property of an object rather than to set it. We can do that in exactly the same way as setting it. If, for instance, we want to get the width of a layer, we can use the following function:

function getWidth(divName) {
   if(document.layers) {//netscape 4.X
      tWidth = mElement(divName,'DoC').width;
   } else {//W3C standard
      tWidth = mElement(divName).offsetWidth;
   }
   return tWidth;
}

This works fine, and because of the way we built it, we can easily extend the function. For example if we want to measure 'nested' layers:

function getWidth(divName) {//add as many arguments 
                            //as layers, starting with the                             //the 'most inside' one (the one 
                            //you want to measure)
   if(document.layers) {//netscape 4.X
      var divs="'" + divName + "','";//start with first argument, 
                                     //the layer we want to measure
      //building string of all layers:
      for (var i=getWidth.arguments.length-1; i>0;i--){//invert the arguments
                                                       //to match the 'inside-out' 
                                                       //pattern
         divs += getWidth.arguments[i]+"','";
      }
      divs += "DoC'";//add the DoC extension because that's 
                     //what we need as last argument for the 
                     //mElement function
      tWidth = eval("mElement(" + divs + ").width");//evaluate the string so it 
                                                    //becomes arguments of the
                                                    //mElement function
   } else {//W3C standard - nesting doesn't matter:
      tWidth = mElement(divName).offsetWidth;
   }
   return tWidth;	
}

Programming the properties of objects in this way, using small, independent functions in combination with our mElement() function, will allow us to create compact, reusable and easily extendable code. It enables the developer to build up a library with functions that change all the possible properties of all possible elements.

All those functions will have been tested, so that they can safely be reused in future projects. Therefore there is no need to worry about DOM-exceptions and property exceptions in the code. The developer will be able to concentrate 100% on the next stage, the 'BEHAVIOR' scripting, or business logic.

Contents:


To page 1To page 2To page 3current pageTo page 3bTo page 4To page 4aTo page 5
[previous][next]


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

URL: http://webreference.com/programming/javascript/dhtmlapps/3a.html