In the first part of this article, I took you through the basics of navigating an HTML document via the DOM, and explained the various methods and collections available to you. If you understood all that (and I hope you did), you should now have a pretty clear idea of how to manipulate a typical HTML document, and change interface elements on the fly.
Let's get cracking!
Making The Swap()
The first item on the agenda today is an illustration of how you can use the DOM to accomplish one of the most popular dHTML applications - the image swap. Take a gander at the following HTML document:
If you remember what I taught you last time, none of this should come as a surprise. I've first defined the "normal" and "hover" state images, and then created a function called imageSwap(), which is called whenever the mouse moves over and out of the image.
The imageSwap() function obtains a reference to the image via its ID, and then obtains the current value of the image's "src" attribute. It then checks the value against the values of the "normal" and "hover" variables, and changes the image source appropriately.
Turning The Tables
Next up, tables. Take a look at the following HTML document, which contains a table with two rows, three cells each.
<html><head></head><body><table border="1" cellspacing="5" cellpadding="5"><tr><td>R1, C1</td><td>R1, C2</td><td>R1, C3</td></tr><tr><td>R2, C1</td><td>R2, C2</td><td id="r2c3">R2, C3</td></tr></table></body></html>
Now, when navigating through a table, there's one important point to be aware of - from the DOM vie, a table must be treated as though it included an additional
<tbody> tag immediately after the
<table> tag and before the
<tr> tags. Adding this to the equation, the page above now looks like this:
<html><head></head><body><table border="1" cellspacing="5" cellpadding="5"><tbody><tr><td>R1, C1</td><td>R1, C2</td><td>R1, C3</td></tr><tr><td>R2, C1</td><td>R2, C2</td><td id="r2c3">R2, C3</td></tr></tbody></table></body></html>
The usual DOM navigation rules now apply, as the following example demonstrates. This script drills down to the last cell of the second row and alters both the background colour of the cell and the text string within it.
<html> <head> </head> <body> <form action="somescript.cgi" method="post" onSubmit="return check();"> Email address: <br> <input id="email" type="text" name="email" size="30"> <br> <input id="spam_me" type="Checkbox" name="spam_me">Yes, I want you to send me megabytes of useless advertisements via email. I love buying crummy products from people who probably flunked kindergarten. <br> <input type="submit"> </form> </body> </html>
and here's the validation script.
In The Frame
It's also interesting to see how the DOM works with frames. Consider the following example, which sets up two frames, "left.html" and "right.html".
<html> <head> </head> <frameset cols="20%,*"> <frame name="left" src="left.html" scrolling="auto" frameborder="no"> <frame name="right" src="right.html" scrolling="auto" frameborder="no"> </frameset> </html>
In order to illustrate how to navigate across frames, I'm going to write a simple script which changes the background colour of the right frame when the appropriate link is clicked in the left frame. Here's the right frame,
<html> <head> </head> <body id="body"> </body> </html>
and here's the left frame - note how each link calls the changeFrameBackground() function with a color as parameter.
Finally, let's take a look at the function which does all the work.
Since this is a frameset, it's necessary to prefix the document.getElementById() method call with a reference to the appropriate frame. This prefix is necessary to identify to the DOM which frame is being called, and to obtain a reference to the correct document tree.
Once a reference to the right frame's
<body> tag is obtained, changing the frame's background colour is a simple setAttribute() away.
The DOM also comes with a bunch of built-in methods designed to manipulate the DOM tree, adding and removing nodes from it on the fly. As you've already seen, a node on the DOM tree could be either an HTML tag or a text fragment - and the DOM comes with methods to add both these types of nodes to the tree, through program code.
I'll begin with the createElement() method, which is used to create a new HTML tag. The following code snippet creates an
<img> tag as a node, and assigns it the name "imageObj".
Once the node has been created, attributes can be assigned to it using the setAttribute() method. For example, the code snippet
is equivalent to the tag
<img src="logo_n.gif" width="50" height="50">
Once the node has been created, the next order of business is to add it to the document tree - a task accomplished by the appendChild() method. The appendChild() method is used to append the newly-created node to a specific location in the tree.
The following code snippet would attach the "imageObj" node as a child of the element identified by "heading1".
Dumbing It Down
Just as you can create HTML tags as nodes, the DOM also allows you to create new text nodes on the tree with the aptly-named createTextNode() method. Here's an example:
Again, the appendChild() method comes into play to attach the new text node to the appropriate branch of the document tree.
Let's see how this plays out in a real-life example. I've put together a simple HTML page, which contains nothing except a set of
<p> tag, using the code snippets I've just demonstrated.
Although the page contains only a single
<p> tag, running the script will add an <img> tag and a line of text to the document tree, which will be immediately visible in the browser.
Of course, the DOM comes with a bunch of other methods as well - here's a brief list, together with an explanation of their function.
removeNode() - remove a node (and/or all its children) from the document tree
replaceNode() - replace a node with another node
cloneNode() - duplicate an existing node
swapNode() - swap the positions of two nodes in the document tree
insertBefore() - insert a node at a specific point in the document tree
Most of these are self-explanatory, and they're not used all that often, so I don't plan to discuss them in detail - they're included here for the sake of completeness.
Should you be interested in learning more about the DOM, there are a number of resources available to you online. Here's a brief list:
The official W3C DOM specifications, at http://www.w3.org/DOM/
DOM sample code at http://www.mozilla.org/docs/dom/samples/
An interesting article on transitioning from proprietary DOMs to the W3C standard, at http://sites.netscape.net/ekrockhome/standards.html
A structural (logical) view of the DOM, at http://www.xml.com/1999/07/dom/xml_dom.gif
An XML introduction to the DOM, at http://www.xml101.com/dom/
And finally, before I go, a final comment. While the new DOM may appear to be far less flexible and easy to use than the proprietary models developers have been used to, the fact remains that it offers one very important advantage: standardization. This DOM has been written in such a manner that every element on a page is finally available to the developer via standard navigation rules, and can be manipulated using standard object methods and properties.
In the short run, it may be difficult - even frustrating - to re-code Web pages as per the new DOM; however, I believe that the effort is well worth putting in, as it immediately ensures that your pages will be viewable across all standards-compliant browsers. It should be noted that much of the confusion in the past (and the resulting profusion of proprietary DOM interfaces) was due to the lack of clear direction from the W3C; now that a DOM specification has been finalized and released, future versions of all the major browsers should support it completely, and we should hopefully see an end to browser incompatibilities that have plagued developers in the past.
Note: All examples in this article have been tested on Mozilla (build 18). Examples are illustrative only, and are not meant for a production environment. YMMV!This article was first published on 26 Apr 2001.