A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter

mouseleave is simple to understand:

Bind an event handler to be fired when the mouse leaves an element, or trigger that handler on an element.

How hard could it be? http://jsfiddle.net/JP6aV/

$(function () {
    var output = $("#output");
    $("#content")
      .mouseenter(function (e) {
          output.text("I'm in!");
    }).mouseout(function (e) {
          output.text("I'm out!");
    });
});

Like many simple things there are some traps under different circumstances. For example, when you put absolutely positioned elements into a page, you might think mouseenter and mouseleave are misbehaving. Watch what happens on http://jsfiddle.net/uUsEM/1/ when the mouse goes into the grey box.

If you've worked with nearly any UI framework before, you'll realize this isn't a misbehavior, but a feature.  But, what if your goal is to use mouseleave and mouseenter to know when the mouse is over the content area, regardless of what might be positioned on top? One solution is to create an element whose sole purpose is to provide mouseenter and mouseleave events for the content area. If the element overlays the content area exactly, has a higher z-index than any other element, and is invisible, then you just might have something that works (see http://jsfiddle.net/5psgc/1/).

$(function() {
    var output = $("#output");
    var content = $("#content");
    var eventSource = $("<div></div>");
    $("body").append(eventSource);

    eventSource.css({
        position: "absolute",
        left: content.offset().left,
        top: content.offset().top,
        width: content.width(),
        height: content.height(),
        opacity: 0,
        "z-index": 999
    }).mouseenter(function(e){
        output.text("I'm in!");
    }).mouseout(function(e) {
        output.text("I'm out!"); 
    });
});

If you try http://jsfiddle.net/5psgc/1/ in Chrome, you'll see the "in" and "out" messages only appear when the mouse is going into, or out of, the content area – no matter where the grey div appears. In IE9 the "in" and "out" messages appear at the wrong places. It's as if Internet Explorer has no empathy for an empty, faceless, soulless div.

The solution?

Set the background-color on the event source. Even though the color doesn't appear, because the opacity is at 0, the events start working as expected.

eventSource.css({
    position: "absolute",
    left: content.offset().left,
    top: content.offset().top,
    width: content.width(),
    height: content.height(),
    opacity: 0,
    "background-color": "#000", // <-- crazy
    "z-index": 999
})

See: http://jsfiddle.net/5psgc/2/

Print | posted @ Thursday, August 18, 2011 9:12 AM

Comments on this entry:

Gravatar # re: A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter
by Ken Tong at 8/18/2011 11:17 PM

But I can no longer select text in #content
  
Gravatar # re: A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter
by Dan G. Switzer, II at 8/19/2011 8:20 AM

I've seen these type of issues crop up with IE and mouseover events before as well:

blog.pengoworks.com/...
  
Gravatar # re: A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter
by scott at 8/19/2011 8:21 AM

Yes. That is an unfortunate side effect. This plays a role in a larger sample to come.
  
Gravatar # re: A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter
by Vladimir Bychkov at 9/1/2011 5:39 PM

Or you can use jQuery .hover event - http://api.jquery.com/hover/
The one with two handlers:
.hover( handlerIn(eventObject),handlerOut(eventObject) )
  
Gravatar # re: A Tale of Backgrounds, Absolutes, mouseleave, and mouseenter
by Yanay at 9/13/2011 3:55 AM

Brilliant! I was going crazy trying to understand (yet again) the wonders of IE. Thanks a lot!
  
Comments have been closed on this topic.
Scott Allen
Posts - 869
Comments - 4493
Stories - 14