Using Event Bubbling and Pseudo Element to Highlight Table Rows

Previous section
.
Option 3: Using Event Bubbling

This method comes from that the mechanism called event-bubbling (read more about it here) can be used as a sink to capture events. Event-bubbling causes all events in the child nodes to be automatically passed to its parent nodes. So this means that no matter what elements are inside a table row <tr>, that element will pass its onmouseover and onmouseout events to their parent <tr> which contains the elements.

So, by traversins the tree of the <table> and attaching onmouseover and onmouseout handlers to <tr> elements, we are guaranteed that the event will be passed to the <tr> even though element that originates the event on another elements, as long as those elements are the descendants of the <tr> - and all content inside a <tr> are! The benefit of this method is speed, the code only needs to traverse the DOM tree of the table once during the initialization. Granted, the gain might not be noticable at all on most tables but the idea can be reused for other purpose.

Here's a working example:

Row A  200x300 $200,000.00 small white  good 2 doors
Row B 200x100 $1,100,300.00 medium yellow good 3 wheels
Row C  1200x2100 $100,000.00 large white good 4 wheels
Row D 20x210 $300.00  medium blue  good 100 wheels
Row E 23x30 $2,300.00 large yellow good 9 wheels

What we need to do is to write a function that traverse the DOM tree of an element and assigns event handlers to the type of element that we want. The option produce only slightly different implementation from the previous one, but it's also more extensible and reusable.  Below is the code that attaches the event handler to a specified element type. This function is made for general purpose, to be re-usable for other purposes.

function propagateEventHandler(currentElement, eventName, elementTagNameToAttachHandlerTo, eventHandlerFunctionToBeCalled, eventHandlerFunctionParam)
{
if (currentElement)
{ // If this is not a tag that we want to attach the handler to, then bail out
// (TagName is "TR", "TD", etc.) if (currentElement.tagName!=elementTagNameToAttachHandlerTo) { return; }
// If the code reaches here, we can be sure that
// the element is what we wanted. // Save the original handler (this is for illustration purpose,
// it is not necessary) if (currentElement[eventName])
{
if (!currentElement.originalEventHandler)
currentElement.originalEventHandler=new Object();
currentElement.originalEventHandler[eventName]=currentElement[eventName];
} // This try_catch needed because IE 7 chokes // when arying to assign event to certain elements
try { currentElement[eventName]=eventHandlerFunctionToBeCalled; // Store parameter within the element itself
if (!currentElement.parameter)
currentElement.parameter=new Object();
currentElement.parameter[eventName]=eventHandlerFunctionParam; } catch(error){}; // Traverse the tree and assign the event handler to every descendants var i=0; var currentElementChild=currentElement.childNodes[i]; while (currentElementChild) { propagateEventHandler(currentElementChild, eventName, elementTagNameToAttachHandlerTo, eventHandlerFunctionToBeCalled, eventHandlerFunctionParam); eventHandlerFunctionToBeCalled);
i++;
currentElementChild=currentElement.childNodes[i]; } } }

elementTagNameToAttachHandlerTo: In our case, we want to assign to all <tr> element.

eventName: What event we want to attach our event handler to. In our case, it will be the function to highlight the row.

currentElement: This is the element (DOM node) that will be traversed. In our case, we set it to our table. This functionwill be called recursively by the table's content (<tr>, <td>, any anything inside), and when the tagName matches elementTagNameToAttachHandlerTo, then the handler is attached to that element.

eventHandlerFunctionToBeCalled: the function to be called when the event occurs. In out case, this is

eventHandlerFunctionParam: this is the parameter to be passed to the function (ie: highlight color in our case) .

To use the function, we just need to call the function somwhere before the closing </body> tag.

<script language="javascript">
propagateEventHandler(document.getElementById("myTable0"),
"onmouseover", "TR", highlightTableRow, "#AA8888");
</script>

That calls associated onmouseover events to the "TR" element with the function highlightTableRow. The #AA8888 is the highlight color.

See the latest code: tableH3.js
Barebone example page: exampleTableHandlerWithBubble.html

A reader asked if the code can be made not to highlight TD elements with a particular id. Let's assume we don't want to highlight the ones with id set to header, then to filter these out, just change the line:

     if (tableCell.tagName=="TD")
with:
     
     if (tableCell.tagName=="TD" && ((!tableCell.id) || 
       (tableCell.id && tableCell.id!="header")))

See the modified code that supports unhighligting of TD that has its id set to "header": tableH3.js
Barebone example page: exampleTableHandlerWithBubble.html

Using "element:hover" Pseudo Class
  
This method is the simplest method of all, but it's not supported by that many browsers. element:hover, along with element:active, and element:focus, are pseudo classes specified by CSS specification.  They are usually reserved for dynamic elements.   It's not clear what dynamic means... but one thing for sure, a link element (ie: <a href...>) is considered a dynamic element, so we can probably assume that dynamic element means "the element will do something when it's clicked."  

By that definition, a table row it not normally a dynamic element, but we can still try assigning a hover class into a <tr> element and see what happens.  Hopefully, the background of the row will change when the mouse is hovering on it.  

Well, it turns out that this approach does work on some browsers.  However, again, since by specification, the dynamic pseudo classes are designated for dynamic elements only (and table rows are usually static); it's not that surprising that most browsers do not support this method.   Based on my testing, it's currently not supported by Internet Explorer (version 6).  It is however, supported by Firefox, Netscape 6.2, Netscape 7 (I'm using Windows XP).

<STYLE><!--
tr:hover
{
  background-color: rgb(153,153,204);
}
//--> </style>
Here's an example.   Remember that currently, this only works on Firefox (I tested with version 1.02) and Netscape 6.2, and Netscape 7.  It looks like this in Firefox:

See W3C info about pseudo classes.

Notes

In addition to changing the background color, changing the text color can also be done by altering the style sheet.  

If a table cell has a sub-table or sub elements, you might need to traverse the tree of the sub-elements to highlight everything.