Michael Wallent
Lead Program Manager, DHTML
Microsoft Corporation
January 5, 1998
The following article was originally published in the Site Builder Magazine (now known as MSDN Online Voices) "DHTML Dude" column. To fully understand Michael Wallent's Dynamic HTML column, you need Internet Explorer 4.0
Object-oriented HTML? Before you start thinking the DHTML Dude had a little too much holiday eggnog last month, let me explain. I've repeatedly discussed the benefits of separating structure, style, content, and behavior. Going object-oriented is just another step in that direction. No, we will not create classes, or subclass, or multiply, or inherit. But it will be interesting.
One of the most commonly used effects is the proverbial mouseover (move your mouse -- and the cursor -- over something on a page, and that something glows, grows, slows, or changes color).
Here is an example of some mouseover code that swaps images.
<html> <body> <a href="javascript:" onmouseover="changeOver('Img1');" onmouseout="changeOut('Img1');"> <img name=Img1 src="Img1.gif"></a><br> <a href="javascript:" onmouseover="changeOver('Img2');" onmouseout="changeOut('Img2');"> <img name=Img2 src="Img2.gif"></a><br> <script> function changeOver(anImage) { if (anImage == "Img1") { document.images[anImage].src = "Img1over.gif"; } else if (anImage == "Img2") { document.images[anImage].src = "Img2over.gif"; } } function changeOut(anImage) { if (anImage == "Img1") { document.images[anImage].src = "Img1.gif"; } else if (anImage == "Img2") { document.images[anImage].src = "Img2.gif"; } } </script> </body> </html>
Remember? This is the way most mouseover effects were done in the past. It was necessary to wrap the images in anchors to get the mouse events. Each event passes the name of the image to act on, and the script conditionally determines the image with which to swap. Yuck.
If I want to add another image to the page, I need to modify the HTML and the script of the page - in three separate places. This is not so good.
I'll make one optimization, and have the image swapper parameterized, and it gets me to this:
<html> <body> <a href="javascript:" onmouseover="changeImage('Img1', 'Img1over.gif');" onmouseout="changeImage('Img1', 'Img1.gif');"> <img name=Img1 src="Img1.gif"> </a><br> <a href="javascript:" onmouseover="changeImage('Img2', 'Img2over.gif');" onmouseout="changeImage('Img2', 'Img2.gif');"> <img name=Img2 src="Img2.gif"> </a><br> <script> function changeImage(anImage, newSource) { document.images[anImage].src = newSource; } </script> </body> </html>
Now if I want to add a new image, I only have to add some new HTML with the event handlers. I no longer need to modify the script.
If I am writing code for Internet Explorer 4.0, I can make some other interesting optimizations. Here is that code:
<html> <body> <img name=Img1 src="Img1.gif" oversrc="Img1over.gif" orgsrc="Img1.gif"> <br> <img name=Img2 src="Img2.gif" oversrc="Img2over.gif" orgsrc="Img2.gif"> <script> function changeOver() { var e; e = window.event.srcElement; if (e.oversrc == null) return; e.src = e.oversrc; } document.onmouseover = changeOver; function changeOut() { var e; e = window.event.srcElement; if (e.orgsrc == null) return; e.src = e.orgsrc; } document.onmouseout = changeOut; </script> </body> </html>
The first optimization I made was to use "event bubbling" (see Bubble Power: Event Handling in Internet Explorer 4.0, Sept. 30, 1997). I no longer need to hook events for each image I want to mouseover; I catch all of the events at the document level. Whenever anything is moused-over or out, my handler is called.
This line of code associates a function with all document onmouseover events:
document.onmouseover = changeOver;
To find out which element the event fired on, I look at the window.event.srcElement property. Because onmouseout and onmouseover events will be firing for all the elements on the page, not just the images I want to effect, I need some way to differentiate the "mouseoverable" from the normal elements.
Which brings us to the second optimization, and the beginnings of "object-oriented-ness." Each image that I want the mouseover effect on has two "Expando" properties. I need to know what the image source should be when the mouse is over an image, and then what to change it back to when the mouse leaves. To do this, I have created two new properties: oversrc and orgsrc. Because the only elements that have the oversrc and orgsrc properties set are those that want the mouseover behavior, I can use the existence of these properties as a test to see if an element participates in the mouseover party.
That's where this line of code comes in:
if (e.orgsrc == null) return;
This code checks whether the source element of the event has an orgsrc property. If it does, I know this image is a mouseover image. If not, I can just return.
If I want to add a new image to the page now and have it participate in the mouseover effect, I have to add only a single line, like this:
<img name=Img3 src="Img3.gif" oversrc="Img3over.gif" orgsrc="Img3.gif">
Furthermore, my script is now totally generic. I can package it up into a .js file, and reuse it on any page on which I want a mouseover effect.
<html> <body> <img name=Img1 src="Img1.gif" oversrc="Img1over.gif" orgsrc="Img1.gif"> <br> <img name=Img2 src="Img2.gif" oversrc="Img2over.gif" orgsrc="Img2.gif"> <script src='mouseover.js'> </script> </body> </html>
We have now successfully separated the content and behavior of the page. The behavior (script) has no idea what images are being swapped around; it knows only what to look for to do the swapping. The content (images) are packaged up nicely in one place. Easy to create, easy to maintain. You could even think of the <IMG> with the new properties orgsrc and oversrc as a new object -- with new, automatic mouseover behavior.
You have now created object-oriented HTML. Have fun.
Michael Wallent, Site Builder Magazine (now known as MSDN Online Voices) monthly columnist on Dynamic HTML, is Microsoft's lead program manager for DHTML.
To fully understand Michael Wallent's Dynamic HTML column, you need Internet Explorer 4.0
Every month, MSDN Online Voices columnist Nadja Vol Ochs explores Web design issues and solutions in Site Lights. And look for articles in the Design section of MSDN Online Web Workshop.