DHTML Behaviors in IE and Mozilla/Firefox
If you look at the source of this page you will find no script tags, yet the top and left-side navigation has mouse rollover effects. Magic? No, DHTML Behaviors. You may have heard of them and dismissed them as IE-only proprietary extension. Well, it turns out you can very easily make them work in Mozilla and Firefox too!
The real beauty and power of Behaviors is how clean of a programming model they are. They allow you to componentize your code, make for simple and clean HTML markup and enable you to develop extensible environments of client-side objects that can interact with each other.
So just how do the rollover effects on this page work?
Each top and side tab image has a class of "rollimg". In the CSS file, the following attaches an HTC component that implements certain behaviors to each element with this class:
.rollimg {
behavior: url(/inc/imageRollover.htc);
-moz-binding: url(/inc/bindings.xml#imageRollover.htc);
}
Above, behavior is used by IE, -moz-binding by Mozilla and Firefox. More on that later. An HTC file is essentially a javascript file in a thin XML wrapper which executes in the context of each element to which it is attached. Within that context, 'element' refers to the element to which the component is attached.
The IMG tag for the tab image also has a custom attribute named "hoversrc". The HTC specifies (using XML tags) that when a mouseover event occurs on the element to which it's attached, this should fire a particular function defined in the HTC. Same with mouseout. Those functions essentially just set element.src to element.hoversrc on mouseover and reverse that on mouseout.
Component properties and methods
The simple rollover effect is just the tip of the iceberg of what Behaviors/HTCs can do. An HTC component can define public properties with associated setter and getter functions. This is used, for example in Microsoft CRM 3.0, to provide a client-side API that allows custom code to read and write complex form fields such as combo boxes, picklists, etc. through such a property. You simply set crmForm.fieldname.DataValue and the component attached to that particular field automatically takes care of setting SELECTED on the right OPTION in a SELECT, for example.
An HTC component can also define custom events and fire those events which will cause code attached to this custom event in the main document to execute. An HTC can provide public methods that the main page can invoke at any time. Here is an example (note that you have to scroll back up to the top to see the caption that shows up):
Invoking a method is as easy as document.getElementById('resources').showCaption().
Getting Behaviors to work in Mozilla and Firefox
HTCs are a Microsoft technology and Mozilla and Firefox don't support it directly. However, they do support a similar technology called XBL. Currently XBL is proprietary to Mozilla but W3C is about to release a slightly modified version of XBL as a standard so the future looks bright for behavior attachment. In the mean time, Dean Edwards has created an emulation layer called moz-behaviors that allows Mozilla and Firefox to use HTCs through XBL.
As shown earlier, XBL's -moz-binding is used to attach a binding specified in bindings.xml to the elements with the HTC (which must be in the same directory) after the #. Note that the string after # is case-sensitive and must exactly match the corresponding declaration in bindings.xml, which is shown below:
<?xml
version="1.0" encoding="ISO-8859-1"?>
<bindings xmlns="http://www.mozilla.org/xbl">
<!-- provide the default path to moz-behaviors.xml (keep the
#behavior suffix) -->
<binding id="behavior" extends="moz-behaviors.xml#behavior"/>
<!-- These ids are case-sensitive! -->
<binding id="imageRollover.htc" extends="#behavior"/>
<binding id="showCaption.htc" extends="#behavior"/>
</bindings>
moz-behaviors.xml is the actual emulation layer from Dean Edwards.
UPDATE: Somewhere along the way, Firefox started returning the -moz-binding property wrapped in double-quotes which caused moz-behaviors.xml to stop working. You can download an updated version which strips out the quotes if present here:
moz-behaviors.xml (minimified)
moz-behaviors-source.xml (the change is on line 65)