The first thing this technique requires is some sort of containing element. This could be the body element, since it's always available as a containing element (and on occasion I've actually found this to be an appropriate choice), but in general, I'd recommend wrapping your links in some logically named container.
Something like this would do the trick:
<a id = "music" href = "#" onclick = "return select(this)">Music</a> |
<a id = "movies" href = "#" onclick = "return select(this)">Movies</a> |
<a id = "books" href = "#" onclick = "return select(this)">Books</a> |
<a id = "food" href = "#" onclick = "return select(this)">Food</a>
</div>>
In the above example, we've wrapped our links in a div named 'navBar'. You'll see why this is critical in a moment (and not just a convenience).
Now let's write the javascript:
{
document.getElementById('navBar').className = _elem.id;
}
Believe it or not, this is all the javascript we need. The real power of this technique lies in the css. But since we haven't written the css yet, our technique is incomplete. Let's fix that now:
#navBar.music #music,
#navBar.movies #movies,
#navBar.books #books,
#navBar.food #food
{
background-color: lightblue;
font-weight: bold;
}
</style>
What does this css mean exactly? Well, that should be easy to answer, and with any good, W3C compliant browser (not IE) it is.
The code #navBar.music #music means that the DOM element whose id is "music" and which is a descedant of a DOM element whose id is "navBar", which also has the class "music" applied to it, will have a lightblue background-color and will have its font-weight set to bold.
This is mouthful to say, so I imagine that it's a bit difficult to understand if you're reading it for the first time. It's helpful to take a second look at the HTML we wrote. Remember that all of the elements we're interested in are wrapped in a parent DIV whose id is "navBar". This allows us to leverage one of css's most powerful techniques: that style rules can "trickle down" from a parent element to its children.
In our case, we're saying that the element whose id is "music" should have a particular style (lightblue background and bold font) only when it lives inside of another element whose id is "navBar" and whose css class is "music".
And since we want all of our "selected" elements to have the same look, we can really slim down our css by simply "chaining" rules together with a comma. This allows us to leverage the same style rule for the elements #movies, #books, and #music.
The full code for this technique is below:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type = "text/javascript">
function select(_elem)
{
var nav = document.getElementById('navBar');
nav.className = _elem.id;
return false;
}
</script>
<style type = "text/css">
#navBar.music #music,
#navBar.movies #movies,
#navBar.books #books,
#navBar.food #food
{
background-color: lightblue;
font-weight: bold;
}
</style>
</head>
<body>
<div id = "navBar">
<a id = "music" href = "#" onclick = "return select(this)">Music</a> |
<a id = "movies" href = "#" onclick = "return select(this)">Movies</a> |
<a id = "books" href = "#" onclick = "return select(this)">Books</a> |
<a id = "food" href = "#" onclick = "return select(this)">Food</a>
</div>
</body>
</html>
Now, if you're remember, a moment ago I said that this css technique was straight-forward for any good, w3c compliant browser (not IE). What did I mean by that? Well, not surprisingly (and as usual) IE6 doesn't adhere to the rules (IE7 actually does a pretty good job).
IE6 does NOT understand combinatorial class selectors. In other words, something like this will make IE6 totally choke:
.abc.xyz { background-color: orange; }
In any descent browser, this style rule would mean that any element that had the css class "abc" and the class "xyz" would get a background-color of orange.
In IE6 it actually defines two distinct css classes (which is completely and totally wrong in every way). IE6's implementation is actually pretty much useless, and if it weren't for a strange quirk in that browser, the technique I'm describing in this blog entry would be pretty much useless as well.
To learn more about IE6's strange css behavior, goto part 3.