JavaScript and OOP for the DOM
I wanted a color transition effect on web page elements when the mouse cursor passed over them – like a:hover, but for any element, not just a link, and a transition over say 0.8 seconds, not just an abrupt change. onmouseout should transition to the original color of the element.
This can be done using onmouseover and onmouseout, but I wanted to set it up for elements of a given tag, class or id. So (after only 2 days) I did it using OOP in JavaScript – listing below. I define a class (strictly a prototype) called ColorP, which will have the behaviour I want, and associate some web page elements with instances of this class. One tricky point is that the method to change the color has to be recursive, and it was difficult to find the syntax for this. Thanks to Pablo Cabrera for ‘arguments.callee’, which must be one of the obscurer backwaters of JavaScript.
The web page body is:
<p id=”test” style=”color: rgb(0,255,0); background: #ff00ff” Hello</p>
<h1 id=”two” “>Goodbye</h1>
The body onload calls:
function start()
{
obj1 = new ColorP(“test”);
obj2=new ColorP(“two”);
return;
}
So 2 objects are created associated with these two elements. We could have traversed the document tree and done this for given tags or classes. The code for ColorP objects is:
function ColorP(id)
{
// data members ///////////////////////////////////////////
var obj;
// time in mS delay before each recursive call
var timeStep;
// initial colors
var red, green, blue;
// color change each step
var rDiff, gDiff, bDiff;
// current color
var red1, green1, blue1;
// target colours and time for transition
var r,g,b,time;
// count and count1 count the transition steps
var count, count1;
// two methods /////////////////////////////////////////////
this.fadeIn = function()
{
if (count==10) {
count=0;
return;
}
count++;
red1+=rDiff;
green1+=gDiff;
blue1+=bDiff;
// set colors to integer values
intR = Math.round(red1);
intG = Math.round(green1);
intB = Math.round(blue1);
obj.style.color=”rgb(“+intR+”,”+intG+”,”+intB+”)”;
setTimeout(arguments.callee, timeStep);
}
this.fadeBack = function()
{
if (count1==10) {
count1=0;
return;
}
count1++;
red1-=rDiff;
green1-=gDiff;
blue1-=bDiff;
// set colors to integer values
intR = Math.round(red1);
intG = Math.round(green1);
intB = Math.round(blue1);
obj.style.color=”rgb(“+intR+”,”+intG+”,”+intB+”)”;
setTimeout(arguments.callee, timeStep);
}
// cnstructor code ///////////////////////////////////////
r=255; // could be passed as constructor parameters
g=0;
b=45;
time=0.7;
// we will do this in 10 steps
// so time for each step = time * 100 milliseconds
timeStep = time*100;
count=0;
count1=0;
obj=document.getElementById(id);
// get colors
styles=obj.getAttribute(“style”);
cols=getColorFromStyles(styles);
if (cols==null) return; // do nothing if can’t obtain color’
// change to numbers
red=parseFloat(cols[0]);
green=parseFloat(cols[1]);
blue=parseFloat(cols[2]);
// work out colour change amounts
rDiff=(r-red)/10.0;
gDiff=(g-green)/10.0;
bDiff=(b-blue)/10.0;
// set current colors to the initial ones
red1=red;
green1=green;
blue1=blue;
obj.onmouseover=this.fadeIn;
obj.onmouseout=this.fadeBack;
}
Unfortunately the code to get the color style is different for IE:
// get foreground color from a set of style attributes
// this returns an array of 3 values – the rgb components
// it works for colors ONLY in the form rgb(a,b,c). If there
// are no styles, or no color defined, it returns
// the equivalent of black
function getColorFromStyles(styles)
{
// in IE, styles is a style object, and styles.color yields the color
// in FF and Opera, styles is a string like ‘color:rgb(1,2,3); background: rgb(4,5,6)’
c=styles.color;
if ( c == undefined ) // NOT IE, so get color:.. out of the string
{
if (styles==null)
return new Array(0,0,0);
// split on ; to separate attributes
pairs=styles.split(“;”);
// search for color
for (i=0; i<pairs.length; i++)
if (pairs[i].search(“color”)!=-1) break;
if (i==pairs.length) // no color..
return new Array(0,0,0);
// separate style from substance (!)
value=pairs[i].split(“:”);
// value[1] is rgb…
col=value[1].slice(5,value[1].length-1);
colours=col.split(“,”);
return colours;
}
else // for IE, so c is like ‘rgb(12,3,4)
{
if (c==”") // no color defined
return new Array(0,0,0);
col=c.slice(4,c.length-1); // slice from rgb(…
// split 3 parts on ,
colours=col.split(“,”);
return colours;
}
}
This works on FireFox, Opera and IE – maybe others








leave a comment