Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






Cross-Browser Style Objects
Pages: 1, 2

In IE4, elements are accessed through a method similar to document.getElementById(), document.all[]; xbStyle merely takes the ID passed to getElementById(), and redirects it to document.all[] instead, which then returns the appropriate element. In Netscape 4, a <div> with an ID can be accessed only through the document.layers[] array, which is a numbered list of all layers on the page; to compensate, xbStyle checks every element in that list against the ID you're looking for, stops when it finds a match, and returns the correct element.



To your script, it doesn't matter whether xbStyle had to pass the ID to a Netscape or an IE-specific function; it sees only the element the function returned. In other words, all you have to worry about is input and output; if you input the ID, you'll get back the element. This is the essence of an API, to hide the hard stuff and let you get real work done.

Below is the source of xbStyle's getElementById() method; take a look behind the curtain and see how the magic works:

if (navigator.family == 'ie4' && navigator.version < 5) {
  document.getElementById = new Function("id", "return document.all[id];");
  }
  else if (navigator.family == 'nn4') {
    document.getElementById = nav4GetLayerById;
  }

function nav4GetLayerById(id) {
  return nav4FindLayer(this, id);
  }

function nav4FindLayer(doc, id) {
var i;
var subdoc;
var obj;
for (i = 0; i < doc.layers.length; ++i) {
  if (doc.layers[i].id && id == doc.layers[i].id)
  return doc.layers[i];
  subdoc = doc.layers[i].document;
  obj = nav4FindLayer(subdoc, id);
  if (obj != null) {
    return obj;
    }
return null;
}

Screen shot.
Screenshot of the "sliding menu" in action

Cross-Browser Sliding Menus

The two functions in our cross-browser sliding menu, showLayer() and hideLayer(), mimic the behavior of our original script, while changing only what is necessary to achieve compatibility. First and foremost, the primary function of xbStyle is to create a cross-browser style object. However, rather than being an object built into all other elements, as it is in the W3C DOM, you must create a new instance of xbStyle for every element whose styles you need to manipulate. You do this by using the xbStyle constructor function, which takes one parameter, an element ID.

var styleObject = new xbStyle("id");

Once you've created a style object, you can use one of xbStyle's built-in methods, which expand on the W3C and 4.0 DOMs, to manipulate style properties. In this example, we'll be using the following methods from xbStyle:

  1. moveBy(x, y): Moves an element a specified number of pixels along the X (horizontal) and Y (vertical) axes, relative to its current position. This method is equivalent to adding to or subtracting from both the "top" and "left" style properties at once.
  2. moveTo(x, y): Moves an element to a fixed point on the page, defined by its X and Y coordinates. This method is equivalent to setting the "top" and "left" style properties at once.
  3. getLeft(): Returns the value of the style object's "left" property as a number. Note that this is different from what the W3C DOM would return because the number includes the unit "px," for "pixels," at the end of it's value. This means the value is a text string, not a plain number. This is important to remember, because while you can compare two numbers as greater than or less than, as in the example below, you can't do the same with text.
  4. setLeft(n): Takes one parameter, a number, and sets the "left" property of the style object.
  5. document.getElementById(id): Yes, it's also part of the DOM, but xbStyle creates a method of the same name for 4.0 browsers that don't support the W3C DOM, with the same general functionality. If the browser does support the DOM, xbStyle does nothing, and the method works just as expected.

The documentation at DevEdge contains a full listing of all xbStyle objects, methods, and properties.

So, let's take a look at the new and improved sliding menu script, now using the methods above (the letters on the left are for reference only):

function showLayer() {
A    var layer = document.getElementById("Layer1"); 
B    var styleObj = new xbStyle(layer); 
C    var left = styleObj.getLeft(); 
     var timeout = setTimeout("showLayer()", 1);
D    if (left <= 0) { 
E      styleObj.moveBy(5, 0); 
     }
     else {
       styleObj.moveTo(0, 50); 
F      clearTimeout(timeout);
     }
   }

   function hideLayer() {
     var layer = document.getElementById("Layer1");
     var styleObj = new xbStyle(layer);
G    styleObj.setLeft("-75"); 
   }
  • A. Here is the first usage of document.getElementById(), now possible in all 4.0 and 5.0 browsers.
  • B. We create a new xbStyle object, which provides an interface to dynamic styles across browsers. Because the various Netscape and IE browsers have wildly varying DHTML style support, we must create a new xbStyle object, and associate it with an HTML element every time to ensure that a style object exists, and that it works consistently.
  • Related Reading

    Designing with JavaScript, 2nd EditionDesigning with JavaScript, 2nd Edition
    By Nick Heinle & Bill Peña
    Table of Contents
    Index
    Sample Chapter
    Full Description

  • C. We store the menu's "left" style property in a variable named left, so that two lines later we can compare its current position with its final position.
  • D. Here we check if some part of the menu is still off the screen by comparing the current left position we've stored as "left" with its final position, 0 pixels from the left edge of the screen. If the menu is still partly offscreen, the function moves the menu, and repeats.
  • E. In the previous version of this script, we moved the menu along 5 pixels by adding 5 to the current left position, and setting the "left" property to that sum. Now, with xbStyle, we can just use the moveBy() method, and save ourselves some math.
  • F. Similarly, we replace the code to return the menu to its original position with this method, moveTo().
  • G. Finally, we use setLeft() to return the menu to its original position.

Try adapting some of your scripts to use XBStyle as well, and you'll save yourself a lot of coding and debugging time while reaching a larger Web audience.

Bill Pena is a freelance Web/information designer and writer. He was also the designer for Safari: Tech Books Online, O'Reilly's online books service.


O'Reilly & Associates recently released (November 2001) Designing with JavaScript, 2nd Edition.

Return to the JavaScript and CSS DevCenter.