Netscape DevEdge

Skip to: [content] [navigation]

Upgrading DHTML pages with xbStyle

Introduction

This technote illustrates using the xbStyle API to upgrade DHTML scripts to support Gecko based browsers such as Netscape 6 with a specific example, ExpCol from Intelinet.com.br

The ExpCol script provides the ability to expand and collapse existing elements (see the demo).

xbStyle is a JavaScript based API that provides the cross-browser support to access and control style properties of HTML elements. Using xbStyle your JavaScript code will only have one code fork and all the browser specific code will be handled internally and automaticaly.

Example

Before xbStyle
// Code fork for Netscape 4.x
if(document.layers) {
  document.myElement.left=100;
}
// Code fork for IE
if(document.all) {
  myElement.style.left=100;
}
// Code fork for Standards Compliant browsers (Netscape 6, IE6, Mozilla)
if(document.getElementById) {
  document.getElementById("myElement").style.left=100+"px";
}
After xbStyle
// using xbStyle
myElement=xbGetElementById("myElement");
myElementStyle=new xbStyle(myElement);
myElementStyle.setLeft(100);

Note: xbGetElementById is a method provided by xbDOM API. This Cross Browser function returns a reference to an HTML element given the value of the element's ID attribute. Notice how in the above sample, a reference to the HTML Element is obtained with xbGetElementById, and a xbStyle object created for the Element. The xbStyle object for the Element provides you with the means to perform many manipulations of the Element's style properties in a cross browser fashion.

More about xbStyle

Read the xbStyle API documentation to get a full picture of the abilities of the xbStyle API. xbStyle provides many methods which allow you to set and retrieve style properties for HTML Elements without having to worry about the differences between differnt browser's implementations.

Instead of worrying about how Netscape Communicator 4, Internet Explorer, Opera and Netscape 6 and other Gecko based browsers set the left position of an Element, all you have to do is create an xbStyle object for your element and call the setLeft method.

A Step by Step Approach: Upgrading with 3 Steps:

Step 1 - Identify places in the Original Script where the JavaScript accesses style properties of HTML elements

// Code fork for Netscape 4.x
if(document.layers) {
  document.myElement.left=100;
}
// Code fork for IE
if(document.all) {
  myElement.style.left=100;
}

Step 2 - Choose one code fork to replace:

I recommend to choose the IE code fork since IE is more similar to the standards based approach (element.style) than Netscape 4. Note that in this step is not recommended to remove the sniffer code (if document.all). Make sure the page is working with IE and then go to the next step.

// Code fork for Netscape 4.x
if(document.layers) {
  document.myElement.left=100;
}
// Code fork for IE
if(document.all) {
  myElement=xbGetElementById("myElement");
  myElementStyle=new xbStyle(myElement);
  myElementStyle.setLeft(100);
}

Since the above change was done in the IE code fork, test with IE and see if the code is working properly.

Step 3 - Clean the code, remove code forks and let xbStyle handle it:

Next comment out the old Netscape 4.x code fork and test with Netscape 4.x, Internet Explorer and Netscape 6.

// Code fork for Netscape 4.x
// if(document.layers) {
//        document.myElement.left=100;
//}
// Code fork for IE
//if(document.all) {    
  myElement=xbGetElementById("myElement");
  myElementStyle=new xbStyle(myElement);
  myElementStyle.setLeft(100);
//}

Notes about upgrade to Intelinet's ExpCol DHTML Conde:

I created this case to illustrate how I updated the ExpCol DHTML script using xbStyle. The following table includes the old DHTML script versus the new DHTML script. Note that the old DHTML script will only work with Netscape 4.x and IE4+. The new script is compatible with Standards Compliant browsers (such as Netscape 6/Mozilla and IE 6) and supports Netscape 4.x and IE4+.

Old ExpCol DHTML script demo
Source-code
Updated version of ExpCol with xbStyle
Source-code

The ExpCol DHTML code uses JavaScript to perform access and manipulation of HTML elements providing an Expand/Collapse effect. The above code is the core of the ExpCol script and is where JavaScript is used to access and control HTML elements in the page. In the following you will see how I easily updated this JavaScript code with xbStyle.

Updating ExpCol DHTML Script

The ExpCol DHTML code is a simple JavaScript code that access existing HTML elements to provide Expanding/Collapsing behavior. This JavaScript code includes 5 simple functions:

// Function to load existing HTML elements
// into the ExpCol global variables.
function expcol_loadElement(id) { ... }

// Function to reset the positioning of the HTML elements
// that have been loaded with expcol_loadElement.
function expcol_reset() { ... }

// Function that collapses the element number n
function expcol_collapse(n) { ... }

// Function that expands the element number n
function expcol_expand(n) { ... }

// This function switches the state between collapsed and 
// expanded.
function expcol_switch(n) { ... }

For all the 5 JavaScript functions I found specific code forks for IE and Navigator 4.x. With xbStyle, only one code fork will be in place and the API itself will take care or each browser's mechanism. In order to start updating I selected the first function expcol_loadElement:

//# ------------------
//# expcol_loadElement 
//# ------------------
//# Load each element into the global array expcol_ids
//#
function expcol_loadElement(id) {
  if(document.layers) {
    expcol_ids[expcol_index]=document.layers[id];
  }       
  if(document.all) {
    expcol_ids[expcol_index]=document.all[id];
  }       
  expcol_index++;
}

Following the approach described above, choose one code fork to change. I selected the document.all code fork. Note that expcol_loadElement is a simple function that retrieve the reference to a given HTML element and store it into an array. Looking more closely at the document.all code fork:

if(document.all) {
  expcol_ids[expcol_index]=document.all[id];
}

document.all returns the object reference to the given id. With xbStyle the code will look like:

if(document.all) {
//  expcol_ids[expcol_index]=document.all[id];
  expcol_ids[expcol_index]=new xbStyle(xbGetElementById(id))
}

Note: To make a reduced and clean code in the last line, I created an instance of xbStyle directly passing the reference returned by xbGetElementById

Additionally, I commented the previous line and left the document.all verification intact. The idea is to replace the content of the IE's code fork with xbStyle code and test it first with IE. Once the IE version is working, xbStyle is working. Then you can remove the other code forks (Navigator 4.x) and replace the proprietary IE's verification (document.all) with a generic verification covering all the browsers you need. The code itself will be working with Netscape 4.x, IE 4+, Netscape Gecko (Netscape 6/Mozilla) and others based in the standards.

Example of changes with other functions

All other changes are based on the same approach. Here is another example for function expcol_expand. Note that expcol_ids[n] will access the xbStyle element that was stored with the previous function (expcol_loadElement):

function expcol_expand(n) {
  ...editing first only the IE code fork...
  if(document.all) {
    //expcol_ids[n].style.visibility="visible";
    expcol_ids[n].setVisibility("visible");
    //collapsedPixels=expcol_ids[n].offsetHeight;
    expcol_ids[n].getHeight();
    for(i=n;i<expcol_index;i++) {
      //expcol_ids[i].style.top=parseInt(expcol_ids[i].style.top)+collapsedPixels;
      expcol_ids[i].setTop(expcol_ids[i].getTop()+collapsedPixels);
    }
  }
}

Once the IE side of the code is replaced with xbStyle in all functions, you are ready to test it with IE. For a complete reference of all xbStyle methods please read the xbStyle API reference.

Testing and doing the clean up

My next step was to test with IE running the xbStyle code. When it's working, the next step is update and remove all the (now) unnecessary code forks including code that is doing browser-specific sniffing, transforming the xbStyle code fork in the default code for all browsers. For example, the expcol_expand became:

function expcol_expand(n) {
//      if(document.layers) {
//          expcol_ids[n].visibility="show";
//          collapsedPixels=expcol_ids[n].clip.height;
//          for(i=n;i<expcol_index;i++) {
//              expcol_ids[i].top+=collapsedPixels;             
//          }
//      }
// xbStyle-based unique fork
expcol_ids[n].setVisibility("visible");
expcol_ids[n].getHeight();
for(i=n;i<expcol_index;i++) {
expcol_ids[i].setTop(expcol_ids[i].getTop()+collapsedPixels);
}
}

Testing with all common browsers

And that's it. Test the page with all common browsers. The above example I tested with Netscape 6/Mozilla, IE4+ and Netscape 4.x. Note the reduced number of lines in the final source-code as well it's much more clear. I recommend xbStyle mostly for DHMTL codes started from scratch, but it have demonstrated to be useful also for existing DHTML scripts.

The following is a collection of recommended resources on how to upgrade web pages to web standards:

A+R