Detecting mouseenter with CSS Animations

While working on a recent project we were amazed to find out that a trivial task as detecting a mouseenter on an element could be such a pain. But yes it was! Unfortunately it was the source of tons of our headaches. I know that most of you reading this would instantly scream out “the heck dude… jQuery: $.mouseenter()!”. And yes, you would have been right, jQuery (and probably other) supports it by simulating the event and makes it possible to be used regardless of the browser. However by targeting the modern browsers only, and performance being an essential part of our project, no jQuery nor any other JavaScript library was available – nothing but vanilla JS.

 

Adding mouseenter event listeners

The mouseenter JavaScript event is proprietary to Internet Explorer, and as such has sort of a limited support among browsers – apart of IE, only Opera and Firefox seem to support it with their newer versions, however no support is available with the WebKit browsers – Chrome and Safari. The example below demonstrates how a handler can be added to each element we want this event to be detect on (as you will see in the next example, it can’t be delegated). Hovering an element should write a message in the right container.

Note that the example won’t work on Chrome and Safari, simply because they do not support the mouseenter event.

 

Delegating the mouseenter event

Another downside of mouseenter event, at least for our project, is that it does not bubble and it isn’t sent when the pointer is moved from one of its descendants’ physical space to its own physical space. In other words it’s impossible to delegate this event, or we can’t detect this event on child elements while attaching a single handler for it on a parent element. The example below listens the parent element for mouseenter event, and it won’t get detected when hovering the child elements. Again, this demonstration won’t work on Chrome and Safari.

 

CSS animations events in help

Recently (well, almost a year ago now), David Walsh wrote about Detecting DOM Node Insertions with CSS Animations, quite astonishing and yet simple technique which uses the CSS Animations event types (animationstart in particular) to identify when a node is inserted. Using this technique can be used to detect mouseenter as well. Mouseenter acts in the same way as the CSS :hover pseudo-class, so by applying a CSS Animation on the :hover state of an element and listening to the appropriate animation event we are able to successfully detect mouseenter. The CSS animation has no visual, but strictly functional purpose.

The example below demonstrates this, and contrary to the previous examples it also works on Chrome and Safari. The mouseentered animation is applied to the .mouseenter:hover CSS class, and with delegator.addEventListener('animationstart', onMouseEnterAnim, false); we are able to detect when an element has been hovered.

And finally, this very same technique can be applied to mouseleave – the mouseenter‘s counterpart – by adding CSS animation to an element in its normal state instead of its :hover state. And of course, applying two CSS animations on both state at the same time can detect both of them as in the example below. With e.animationName we can determine the exact event.

» All demo examples in one page