Introduction to Object Oriented DHTML

Object oriented programming (OOP) takes a little to get used to, but I assure you if you've understood everything up until now, you (probably) won't have any difficulty understanding this lesson. Using Object Oriented DHTML is the next progression and will allow you to build more sophisticated scripts in an organized way.

You want to use objects whenever you need to create more than one of something. By creating one generic object, you can use it to create any number of them without duplicating much of your code. This has a big impact on your coding because it means you don't have to write as much code, everything is organized nicely, and the JavaScript will execute faster.

You can view Netscape's JavaScript tutorial for a comprehensive explanation of how to create new objects. On this lesson I'll give a brief overview of OOP and show how to make a simple reusable object for working with layers. Everything I do in this tutorial from this point on will be object-based so it's a good idea to follow along.

OOP Overview

When you create objects, really what you are doing is collecting a lot of different variables into a nice neat package which you can then easily access at a later time. Each object is it's own package, and the variables in that package are referred to as properties. You can then write functions which manipulate only the variables (properties) of that object, these are referred to as methods.

Using objects are helpful because they are designed so that they can be cloned to make many different objects that will be used similarly. Without confusing you yet, say we had a generic object named "block". Then we decided we want to have several blocks (block1, block2, block3 etc.) that all had similar variables (height, width, depth etc.). Using object oriented programming, the variables in the blocks are all collected together in this format:

Object Name block1 block2 block3
property 1 block1.width block2.width block3.width
property 2 block1.height block2.height block3.height
property 3 block1.depth block2.depth block3.depth

This is the basic set-up for all JavaScript objects:

function objectName(arguments) {
	this.propertyName = somevalue
}

So to create this generic "block" object, the code would look something like this:

function block(width,height,depth) {
	this.width = width
	this.height = height
	this.depth = depth
}

Notice that any variable defined with "this" in front of it becomes a property of the object. Many of the properties will initially be assigned values based on those passed in the arguments, but you can also set other default properties to whatever you'd like, for example:

function block(width,height,depth) {
	this.width = width
	this.height = height
	this.depth = depth
	this.color = "red"
}

...would make the width, height, and depth change depending on how it's initialized, but all the blocks would have a color property of "red".

Once this generic object function is created, you can clone objects based on this code, this is referred to as creating an instance of an object. The format for creating instances of a self-defined object is as follows:

newObjectName = new objectName(arguments)

So to create the block objects named block1, block2, and block3 you'd write:

block1 = new block(10,20,30)
block2 = new block(5,20,10)
block3 = new block(15,30,15)

After they're defined you can do whatever you'd like with the object, check it's properties, or change them. Properties of an object work exactly the same way as normal variables do.

Once you've got the object function itself created, you can extend the functionality of the object by creating methods for it. The format for creating a method is as follows:

function objectName(arguments) {
	this.propertyName = somevalue
	this.methodName = methodFunction
}

function methodFunction(arguments) {
	// write some code for the object
}

The methodFunction() works like any other function, except when you call the function you add the name of the object you want to apply the function to:

newObjectName.methodFunction()

So using this idea, we can add a method to the block object that calculates the volume of the block and returns the value:

function block(width,height,depth) {
	this.width = width
	this.height = height
	this.depth = depth
	this.color = "red"
	this.volume = blockVolume
}
function blockVolume() {
	return this.width*this.height*this.depth
}

To find the volume of block1 you write:

block1.volume()

newobjects1.html has this simple block object and allows you to check the values of the properties and the volume using alert's.

Objects and Layers

Using the concepts from previous lessons, we can apply object oriented programming to make working with layers a much easier task. Instead of always re-writing initialization code for pointer variables, you can create generic objects that do the same thing with just one line of code.

Recall again what pointer variables are doing:

if (ns4) layer1 = document.layer1Div
else if (ie4) layer1 = layer1Div.style

...which is synonymous with:

if (ns4) layer1 = document.layers["layer1Div"]
else if (ie4) layer1 = document.all["layer1Div"].style

In this case, layer1 is a reference variable which points to the CSS properties of the layer named "layer1Div". If you've been using pointer variables on your own, you'll know that to create many pointer variables is rather cumbersome. To solve that problem I'm going to make a generic object that creates a css property which does the same thing as pointer variables do:

function layerObj(id) {
	if (ns4) this.css = document.layers[id]
	else if (ie4) this.css = document.all[id].style
}

To use this layerObj object, you can now initialize your pointer variables with only:

layer1 = new layerObj("layer1Div")

Once the layer1 object is initialized you can access the css properties of "layer1Div" by using:

layer1.css.left
layer1.css.top
layer1.css.visibility
etc....

So all that's really changed is the extra css between everything. We can further extend the layerObj object by automatically defining x and y properties which will represent the left and top properties of the layer:

function layerObj(id) {
	if (ns4) {
		this.css = document.layers[id]
		this.x = this.css.left
		this.y = this.css.top
	}
	else if (ie4) {
		this.css = document.all[id].style
		this.x = this.css.pixelLeft
		this.y = this.css.pixelTop
	}
}

So again if we were to create a layer1 object:

layer1 = new layerObj("layer1Div")

The layer1 object would have these properties:

layer1.css
layer1.x
layer1.y

Note that we can now use x and y as our properties because this is our own object we're working with. I was using xpos and ypos before because Netscape already included those properties as part of it's own Layer object. Since we're creating a new object we can name the properties whatever we like.

Example: newobjects2.html shows an example using this object and allows you to check the values of the properties.

Making Methods

We can extend the functionality of the layerObj object to make it easy to manipulate layers just as we can create separate individual functions. Recall in the Moving Layers lesson I made a generic functions that can be used to move a layer to any position on the screen:

function moveBy(obj,x,y) {
	obj.xpos += x
	obj.left = obj.xpos
	obj.ypos += y
	obj.top = obj.ypos
}
function moveTo(obj,x,y) {
	obj.xpos = x
	obj.left = obj.xpos
	obj.ypos = y
	obj.top = obj.ypos
}

Those functions translated into methods of the layerObj object look like this:

function layerObj(id) {
	if (ns4) {
		this.css = document.layers[id]
		this.x = this.css.left
		this.y = this.css.top
	}
	else if (ie4) {
		this.css = document.all[id].style
		this.x = this.css.pixelLeft
		this.y = this.css.pixelTop
	}
	this.moveBy = layerObjMoveBy
	this.moveTo = layerObjMoveTo
}
function layerObjMoveBy(x,y) {
	this.x += x
	this.css.left = this.x
	this.y += y
	this.css.top = this.y
}
function layerObjMoveTo(x,y) {
	this.x = x
	this.css.left = this.x
	this.y = y
	this.css.top = this.y
}

Again if we were to create a layer1 object:

layer1 = new layerObj("layer1Div")

We can then move the layer by using either the moveBy() or moveTo() methods:

layer1.moveBy(-5,10)
layer1.moveTo(100,100)
etc.

Example: newobjects3.html shows and example using these methods.

Where to go from here

This tiny object would only be used in very specific instances where all you need to do is move the layer around in a simple manner. The way I've made this object doesn't account for nested layers, so if you need to use nested layers you'd have to change the code to include the extra parent layers. The above object is actually deriviative of The Dynamic Layer Object. It is a unified cross-browser object oriented solution for DHTML.

Home Next Lesson: BrowserCheck Object
copyright 1998 Dan Steinman