Reputation: 28225
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
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
Reputation: 322542
Here's one example.
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