Changing Styles

Internet Explorer's revolutionary DOM (Document Object Model) allows almost all the styles of a page element to be both readable and writeable at any time. This makes IE 4.0's Dynamic HTML system fundamentally superior. Most likely in the version 5 of the browsers this will be put on more even ground. However it is possible to mimic IE 4.0's functionality in Netscape 4.0 by using some clever tricks and document.write()-ing new layers with different styles. That is what most of this lesson is based around.

Changing the Background Color of a Layer

In Netscape to change the background color of a layer you have to set the bgcolor property of it's document object:

document.layer["layerName"].document.bgColor = "red"

In IE, you set the backgroundColor property of the layer:

document.all["layerName"].style.backgroundColor = "red"

So a cross-browser function for both would look like this:

function setBGColor(id,nestref,color) {
	if (ns4) {
		var lyr = (nestref)? eval('document.'+nestref+'.document.'+id):document.layers[id]
		lyr.document.bgColor = color
	}
	else if (ie4) {
		document.all[id].style.backgroundColor = color
	}
}

View bgcolor1.html for a background color example.

Font Colors

To change the color of the text in a layer in IE is dead simple. Again, you'd just change the CSS color style of the element:

document.all[id].style.color = "#FF0000"

But to do the same in Netscape will require a document.write() to rewrite the layer with a different style. One way that works pretty good is to use the antient FONT tag:

<DIV ID="mytext"><FONT COLOR="#FF8000">My Text</FONT></DIV>

And then using the layerWrite() function, rewrite that layer with a new color:

layerWrite('mytext',null,'<FONT COLOR="#008000">My Text</FONT>')

However, I will pass that over and avoid the FONT tag altogether. The other general way to accomplish the task, is to predefine the styles you're going to use:

<STYLE TYPE="text/css">
<!--
.orange {color:#FF8000;}
.green {color:#008000;}
#mytext {position:absolute; left:50; top:100;}
-->
</STYLE>

And instead of using the FONT tag, I'll use the SPAN tag:

<DIV ID="mytext"><SPAN CLASS="orange">My Text</SPAN></DIV>

Then my javascript function rewrites the layer and has the CSS CLASS as an argument:

function mytextColor(color) {
	layerWrite('mytext',null,'<SPAN CLASS="'+color+'">My Text</SPAN>')
}

In my case I can execute the function with either of the following commands:

mytextColor('orange')
mytextColor('green')

View fontcolor1.html for this font color example

Text Rollovers

The primary use for changing font colors is to create text-based rollovers to replace the need for image-based rollovers. I've successfully created a system for doing this, however it's not a perfect solution, tedius and a little ugly. I'll show the way I first tried to do it, however I'll admit it doesn't work all that good. Still though I believe it's important to show you the thought process involved in fixing such problems.

Like the font color example, I just manually coded each of the styles I wanted to use. In my case I have 4 layers each containing the link which will change color when you roll over and off them:

<STYLE TYPE="text/css">
<!--
A.red {color:red;}
A.blue {color:blue;}
#link0Div {position:absolute; left:50; top:50;}
#link1Div {position:absolute; left:50; top:70;}
#link2Div {position:absolute; left:50; top:90;}
#link3Div {position:absolute; left:50; top:110;}
-->
</STYLE>

Since this is just a demo, I've used generic links and names for the layers:

<DIV ID="link0Div"><A CLASS="blue" HREF="page1.html" onMouseOver="linkOn('link0Div','page1.html','Link 1')">Link 1</A></DIV>
<DIV ID="link1Div"><A CLASS="blue" HREF="page2.html" onMouseOver="linkOn('link1Div','page2.html','Link 2')">Link 2</A></DIV>
<DIV ID="link2Div"><A CLASS="blue" HREF="page3.html" onMouseOver="linkOn('link2Div','page3.html','Link 3')">Link 3</A></DIV>
<DIV ID="link3Div"><A CLASS="blue" HREF="page4.html" onMouseOver="linkOn('link3Div','page4.html','Link 4')">Link 4</A></DIV>

Notice in the links I've only stated the onMouseOver events. This was a little trick I came up with. First it displays the onMouseOver, and when the link changes color, I rewrite the contents of the layer but replace the onMouseOver with an onMouseOut. That way there's never any interuption in the rollover sequence.

I have a separate JavaScript function for each state of the link:

function linkOver(id,link,text) {
	layerWrite(id,null,'<A CLASS="red" HREF="'+link+'" onMouseOut="linkOut(\''+id+'\',\''+link+'\',\''+text+'\')">'+text+'</A>')
}

function linkOut(id,link,text) {
	layerWrite(id,null,'<A CLASS="blue" HREF="'+link+'" onMouseOver="linkOver(\''+id+'\',\''+link+'\',\''+text+'\')">'+text+'</A>')
}

The format of each of my links are the same, so I only needed to make the layerName (id), hyperlink location (link), and the displayed text (text), variables.

View textrollover1.html for this text rollover example

However, in Netscape that example doesn't seem to work quite properly. The onMouseOut's don't seem activate if you roll between links too quickly. You need a way of double-checking to see if some of links are still "on". So I decided to change how I set things up. I built a 2-dimensional array to keep track of the layer names, links, text, and a flag (true/fase) to indicate whether link is highlighted or not highlighted respectively.

link = new Array()
link[0] = new Array('link0Div','link1.html','Link 1',false)
link[1] = new Array('link1Div','link2.html','Link 2',false)
link[2] = new Array('link2Div','link3.html','Link 3',false)
link[3] = new Array('link3Div','link4.html','Link 4',false)

Now we have a way of accessing any of the layer/links by numbers (0,1,2,3). To access any one of the link values I just write link[x][0] for the layer name, link[x][1] for the hyperlink etc. where x is the number of the link.

The linkOver() and linkOut() functions have to be updated to account for these changes. In those functions I added a line to set the flag value of the link (the link[x][3]) - true meaning "on" and false meaning "off". It was when onMouseOut occured that Netscape had the problems with. So to correct it, I do a little check the next time you do an onMouseOver (and hence call the linkOn() function) it goes through a loop to check the value of the flag of each link, if it's true it automatically calls the linkOut() function to force the link off.

function linkOver(num) {
	if (ns4) {
		for (var i=0;i<link.length;i++) {
			if (link[i][3]==true) linkOut(i)
		}
	}
	link[num][3] = true
	layerWrite(link[num][0],null,'<A CLASS="red" HREF="'+link[num][1]+'" onMouseOut="linkOut('+num+')">'+link[num][2]+'</A>')
}

function linkOut(num) {
	link[num][3] = true
	layerWrite(link[num][0],null,'<A CLASS="blue" HREF="'+link[num][1]+'" onMouseOver="linkOver('+num+')">'+link[num][2]+'</A>')
}

The HTML for the links also have to be updated, the linkOver() and linkOut() functions only need to pass the index of the link now.

<DIV ID="link0Div"><A CLASS="blue" HREF="page1.html" onMouseOver="linkOver(0)">Link 1</A></DIV>
<DIV ID="link1Div"><A CLASS="blue" HREF="page2.html" onMouseOver="linkOver(1)">Link 2</A></DIV>
<DIV ID="link2Div"><A CLASS="blue" HREF="page3.html" onMouseOver="linkOver(2)">Link 3</A></DIV>
<DIV ID="link3Div"><A CLASS="blue" HREF="page4.html" onMouseOver="linkOver(3)">Link 4</A></DIV>

And there we have it, a working text rollover.

View textrollover2.html to view this text rollover example.

Of course, this technique can be used to change more than just the color, you can change other properties of the text by just defining your CSS values differently. The following makes the underline disappear, and when the link is on it makes the text in italics:

A.blue {color:blue; text-decoration:none;}
A.red {color:red; text-decoration:none; font-style:italic;}

View textrollover3.html') for a text rollover with italics.

Font Scaling

Font scaling (making text grow or shrink) is technically possible with Dynamic HTML, however the truth is it by no means is the best technology to accomplish it with. Something like Flash is much better and faster, and with the upcoming Flash 3.0 vector graphics/animation format it looks like it'll definately be the choice of developers in the next version of the browsers. But until that time, you can certainly play around and accomplish something similar with just plain old JavaScript and CSS.

The concept of font scaling is exactly the same as the technique for changing colors. You first pre-define the CSS styles you're going to use:

.s10 {font-size:10pt;}
.s15 {font-size:15pt;}
.s20 {font-size:20pt;}
.s26 {font-size:26pt;}

And have a layer that first displays one of them:

<DIV ID="welcomeDiv"><SPAN CLASS="s10">Welcome</SPAN></DIV>

Then is just a matter of writing a function that re-writes that layer pointing to different style:

function fontScale(size) {
	layerWrite('welcomeDiv',null,'<SPAN CLASS="s'+size+'">Welcome</SPAN>')
}

For the following example I just have simple links that make the text bigger or smaller:

<A HREF="javascript:fontScale(10)">10 pt</A>
<BR><A HREF="javascript:fontScale(15)">15 pt</A>
<BR><A HREF="javascript:fontScale(20)">20 pt</A>
<BR><A HREF="javascript:fontScale(26)">26 pt</A>

View fontscaling1.html for this font scaling example.

But of course that's not very fun. We can of course animate our font scaling so that the text appears to grow, or shrink if we want. To do that we'll need a lot of styles defined - one for each step in the sequence. It's easiest to do that in a loop to write out each style. I decided to have a font-scaling which goes from 10 to 50 points:

var sizestr = '<STYLE TYPE="text/css">\n'
for (var i=10;i<=50;i++) sizestr += '.s'+i+' {font-size:'+i+'pt;}\n'
sizestr += '</STYLE>'
document.writeln(sizestr)

I kept the function for cycling through the styles pretty simple. I just have a variable size which keeps track of which style is currently shown, and increment that by one each iteration. The if statement (if (size<50)) will determine when to end the loop.

var size = 10
function scaleWelcome() {
	if (size<50) {
		size++
		layerWrite('welcomeDiv',null,'Welcome')
		setTimeout('scaleWelcome()',30)
	}
}

Then just activate the function and it'll make the text grow incrementally larger.

View fontscaling2.html for an animated font-scaling.

That example has the text stuck to the left - as the text grows it doesn't re-adjust to the new size and ends up looking a little awkward. To solve that problem you can center the text by using either <DIV ALIGN="CENTER"> or the old <CENTER> tag. Although when you do this it's probably best to have a container layer with which you control the position with, then your text layer resides within it and centered. In the following example I've shown how to set that up.

View fontscaling3.html for a "centered" font-scaling.

Home Next Lesson: External Source Files
copyright 1998 Dan Steinman