DHTML micro API

On this page I give my micro-API for writing correct cross-browser DHTML. You can use this function to gain access to the HTML element you want to influence.

It will pass you the HTML element you asked for, regardless of browser DOM. Of course the element must have a proper ID and, if your script must work in Netscape 4, should have a position defined in the style sheet.

The only problem is nested layers in Netscape 4. If you don't need nested layers, use the very simple Version A, if you do need them, use the slighly more complex Version B

Version A

This is the simplest version, without a check for nested layers in Netscape 4.

function getObj(name)
{
  if (document.getElementById)
  {
  	this.obj = document.getElementById(name);
	this.style = document.getElementById(name).style;
  }
  else if (document.all)
  {
	this.obj = document.all[name];
	this.style = document.all[name].style;
  }
  else if (document.layers)
  {
   	this.obj = document.layers[name];
   	this.style = document.layers[name];
  }
}

It's called like this:

var x = new getObj('layername');

Now the function create a new JavaScript object x. It goes through all possible DOMs and if it finds the one that the browser supports it sets this.obj and this.style. The this keyword makes sure that the two properties obj and style are added to the new object x.

Using the object

Please note that you cannot do anything with the object x itself, it is merely a container for its two properties:

  1. .obj, giving access to the actual HTML element. You have to use this property to read out or set anything else than styles.
  2. .style, giving access to the styles of the HTML element. You have to use this property to read out or set the styles of the element.

So to alert the ID of the object, do

alert(x.obj.id)

After all the ID is a property of the object itself, not of the style. To change the top coordinate, do

x.style.top = '20px';

top is a style, so you should use the style property.

Version B

If you use nested layers in Netscape 4, the function becomes slightly more complex. It is necessary to search inside the layers for the layer with the correct name. The call and use of the function doesn't change.

function getObj(name)
{
  if (document.getElementById)
  {
  	this.obj = document.getElementById(name);
	this.style = document.getElementById(name).style;
  }
  else if (document.all)
  {
	this.obj = document.all[name];
	this.style = document.all[name].style;
  }
  else if (document.layers)
  {
	this.obj = getObjNN4(document,name);
	this.style = this.obj;
  }
}

function getObjNN4(obj,name)
{
	var x = obj.layers;
	var foundLayer;
	for (var i=0;i<x.length;i++)
	{
		if (x[i].id == name)
		 	foundLayer = x[i];
		else if (x[i].layers.length)
			var tmp = getObjNN4(x[i],name);
		if (tmp) foundLayer = tmp;
	}
	return foundLayer;
}

If the browser is Netscape 4 (if (document.layers)) the function sends the document and the name of the desired layer to a special function getObjNN4().

getObjNN4()

This is a recursive function, meaning that it calls itself when necessary. It expects two parameters, the object in which it should search and the name for which it should search.

function getObjNN4(obj,name)
{

Initially the object is the document. Make two variables, one containing all the layers in the object and one to hold the layer once it's found.

	var x = obj.layers;
	var foundLayer;

Now we go through all layers in the object.

	for (var i=0;i<x.length;i++)
	{

If a layer has the correct name we found what we want and set the return value foundLayer to this layer.

		if (x[i].id == name)
		 	foundLayer = x[i];

If the layer doesn't have the correct name, see if it contains more layers. If it does we call getObjNN4() again, but now the object in which it should search is not the document but the layer. The value that this new call returns is stored in tmp.

		else if (x[i].layers.length)
			var tmp = getObjNN4(x[i],name);

If the function has actually returned the layer, set the return value of this function to the layer:

		if (tmp) foundLayer = tmp;
	}

Finally return the calculated return value. It can have two values: undefined (layer not (yet) found) or a reference to the layer.

	return foundLayer;
}

In the end this return value is returned to the main getObj function. Both this.obj and this.style are set to the layer, since Netscape 4 doesn't make any difference between the two.

  else if (document.layers)
  {
	this.obj = getObjNN4(document,name);
	this.style = this.obj;
  }

Example

An example of Version B, especially for Netscape 4. Fill in the number of a layer and press the button. The layer will become invisible.

Layer 1
Layer 2
Layer 3
Layer 8
Layer 4
Layer 9
Layer 5
Layer 6
Layer 7