brettkelly
brettkelly

Reputation: 28225

How can I hide this overlay element intelligently?

The site I'm working on has a collection of navigation elements across the top ("Products", "Company", etc.). When you mouse over the Products link, an overlay appears that shows a list of products with links to each. There's a small link at the top of the container that, when clicked, closes the container. All of this works as advertised.

The client has asked that, once a user's mouse pointer is a sufficient distance from the overlay element, the overlay element would close (without them having to click the 'close' link). This element appears on multiple pages that have disparate content, so I'm afraid it won't be as simple as adding a mouseover listener to another single element within the page and have it work everywhere. My question, I suppose, is this: is there a relatively easy way to know when the mouse cursor is x pixels away from this container and trigger an event when this occurs?

My other thought is that I could just find several elements on the page that fit this criteria and add mouseover listeners to each, but I'm assuming there's a more elegant way of handling this.

Thanks in advance - and please let me know if more detail is needed.

Upvotes: 2

Views: 747

Answers (2)

Brock Adams
Brock Adams

Reputation: 93533

Why not use a mouseout event with a timer?

var zGbl_OverlayCloseTimer      = '';

OverlayElement.addEventListener ("mouseout",  CloseOverlayWithDelay, false);


function CloseOverlayWithDelay (zEvent)
{
    if (typeof zGbl_OverlayCloseTimer == "number")
    {
        clearTimeout (zGbl_OverlayCloseTimer);
        zGbl_OverlayCloseTimer  = '';
    }

    zGbl_OverlayCloseTimer      = setTimeout (function() { CloseOverlay (); }, 333);
}


function CloseOverlay ()
{
    ...
}

Upvotes: 1

user113716
user113716

Reputation: 322542

Here's one example.

http://jsfiddle.net/CsgFk/

Calculate the bounds you want around the overlay, and set up a mousemove hanlder on the document, which tests to see if the mouse is outside the bounds.

EDIT: It may be worthwhile to unbind the mousemove from the document when the overlay is hidden, and rebind it when revealed so that the mousemove isn't constantly firing for no reason. Or at the very least, have the mousemove handler check to see if the overlay is already hidden before hiding it.

HTML

<div id='overlay'></div>​

CSS

#overlay {
    width: 200px;
    height: 200px;
    background: orange;
    position: relative;
    top: 123px;
    left:23px;
}​

jQuery

var $ovl = $('#overlay');
var offset = $ovl.offset();
var height = $ovl.height();
var width = $ovl.width();

var bounds = {top: offset.top - 100,
              bottom: offset.top + height + 100,
              left: offset.left - 100,
              right: offset.left + width + 100
             }

$ovl.mouseenter(function() {
    $ovl.stop().animate({opacity:1});
});

    $(document).mousemove(function(e) {
    if(e.pageX < bounds.left ||
       e.pageX > bounds.right ||
       e.pageY < bounds.top ||
       e.pageY > bounds.bottom) {
           $ovl.stop().animate({opacity:.3});
    }
});​

EDIT:

Here's another idea (although it is heavily dependent on your layout). Place the overlay inside a container that has a large padding and remove the overlay when the pointer performs a mouseleave on the container. Again, this may not be feasible in your layout.


EDIT:

One other idea would be to set a delay on the code used to remove the overlay. Its not as precise, but may yield a sufficiently desirable effect.

Upvotes: 3

Related Questions