I would like to propose something slightly more elegant (at least shorter):
Using delegated mouse events:
$('#mainTable').on('mouseenter mouseleave', 'tr', {el: false}, function (e) {
var hl = e.data.el;
hl && hl.removeClass('hover');
e.data.el = (e.type === 'mouseenter') ?
$(this).addClass('hover') :
$(this).parent().closest('tr:hover').addClass('hover');
});
It stores the currently highlighted node in the (persistent) delegated data object and handles the mouse events, as follows:
- If the mouse enters an element (the innermost hovered
tr
), remove the current highlight and highlight current element.
- If the mouse leaves an element, highlight the closest
hovered
ancestor tr
instead of the current one.
The main advantages of solutions using event delegation (such as $.delegate()
and $.on()
with a selector) are attaching only a single event listener (compared to potentially dozens, hundreds or more using traditional, per-element, methods) and being able to support dynamic changes to the element.
I chose this solution over the use if the mouseover
event since I believe the enter/leave events should provide better performance, as they do not bubble.
Note:
It has a problem with jQuery 1.9.x but works with the rest, as far as I tested, including newer and older releases. This is due to an issue with the :hover
pseudo-selector in that version.
CSS4
CSS level-4 has a suggested feature that can enable this behavior using CSS only:
tr, !tr:hover tr:hover {
background-color: transparent;
}
tr:hover {
background-color: #DDFF75;
}
Of course, since this feature is not currently final and is not supported by any major browser at the moment, this section will serve as future reference.