Autonomous Machine

Emulating :hover in IE6 with Prototype and Low Pro

A common technique for building UI items that respond to a hover, such as drop downs, is to write CSS rules that make a child UL appear when an enclosing element is moused over:

<ul>
    <li>
         <a href="/item1">Item 1</a>
         <ul>
                <li><a href="subitem1">Subitem1</a></li>
                <li><a href="subitem2">Subitem2</a></li>
                <li><a href="subitem3">Subitem3</a></li>
         </ul>
    </li>
    <li><a href="/item2">Item 2</a></li>
    <li><a href="/item3">Item 3</a></li>
</ul>
ul li ul {
  display: none;
}

ul li:hover ul {
  display: block;
}

Which works everywhere except under IE6. I've seen some posts on the web that suggest adding event listeners to the elements that need to detect hovering, and then having an event handler add a CSS class to the elements. Unfortunately, most of these posts recommend attaching listeners to the the mouseover and mouseout events, which is problematic if the elements have any children. When the child elements fire their own events, the result will be an annoying flicker.

One option is to add conditionals the event handler functions to make sure only the desired events are being responded to. But a simpler solution in this case is to use IE's non-standard mouseenter and mouseleave events. Here's an example in LowPro:

var ElementWithManualHover = Behavior.create({
    onmouseenter: function() {
        this.element.addClassName('hover');
    },
    onmouseleave: function() {
        this.element.removeClassName('hover');
    }
});

if (Prototype.Browser.IE6) {
    Event.addBehavior({
       'ul li': ElementWithManualHover 
    });
}

I'm using some extended browser detection to apply these behaviors only to IE6. You could do the same thing on your own in a few more lines of code.

This, of course, is only a good technique if you're already using Prototype. If you aren't, take a look at jQuery's hover.