13

Let's suppose I have two spearate divs, A and B, which overlap at a corner:

+-----+
|     |
|  A  |
|   +-----+
+---|     |
    |  B  |
    |     |
    +-----+

I want to trigger an event when the mouse leaves both A and B.

I tried this

$("#a, #b").mouseleave(function() { ... });

But this triggers the event if the mouse leaves either node. I want the event to be triggered once the mouse is not over either node.

Is there an easy way to do this? I had an idea that involved global variables keeping track of the mouse state over each div, but I was hoping for something more elegant.

2
  • 1
    I've seen this before. I think you can calculate the combined coordinates using .offset() for each #a, #b, and when the mouse position is no longer over the combined coordinates, $('#a, #b').trigger('mouseleave'); . Commented Dec 19, 2011 at 5:41
  • @JarredFarrish That sounds even worse that the solution I had in mind. Keeping track of the offset of the cursor can be pretty unwieldy. Commented Dec 19, 2011 at 6:12

3 Answers 3

20

I encounter this problem all the time, and my 'quick fix' if it fits what I'm doing is the following;

var timer;

$("#a, #b").mouseleave(function() {
    timer = setTimeout(doSomething, 10);
}).mouseenter(function() {
    clearTimeout(timer);
});


function doSomething() {
    alert('mouse left');
}

Fiddle : http://jsfiddle.net/adeneo/LdDBn/

Sign up to request clarification or add additional context in comments.

4 Comments

+2.5 That's pretty slick! I like how you only need one global variable and the process doesn't require as much finagling as the more obvious solutions.
If you can position one of the elements absolutely, there is no need for a hack like this. See here.
@muhd - position absolute has nothing to do with it, that's event propagation, which happens when you nest elements like that, but the answer was meant as an alternative to nesting, as that's not always possible.
Your quick fix seems to much quick solutions for me :)
3

If you nest the second container inside the first there is no need for a complex jQuery solution:

http://jsfiddle.net/5cKSf/3/

HTML

<div class="a">
    This is the A div
    <div class="b">
        This is the B div
    </div>
</div>

CSS

.a {
    background-color: red;
    width: 100px;
    height: 100px;
    position: relative;
}

.b {
    background-color: blue;
    width: 100px;
    height: 100px;
    position:absolute;
    top: 50px;
    left: 50px;
}

JS

$('.a').hover(function() {
   alert('mouseenter'); 
}, function() {
   alert('mouseleave');
});

Comments

0

I guess you can achieve this using something like:

var mouseLeftD1 = false;
var mouseLeftD2 = false;

$('#d1').mouseleave(function() {
  mouseLeftD1 = true;
  if(mouseLeftD2 == true) setTimeout(mouseLeftBoth, 10);
}).mouseenter(function() {
  mouseLeftD1 = false;
});

$('#d2').mouseleave(function() {
  mouseLeftD2 = true;
  if(mouseLeftD1 == true) setTimeout(mouseLeftBoth, 10);
}).mouseenter(function() {
  mouseLeftD2 = false;
});

function mouseLeftBoth() {
  if(mouseLeftD1 && mouseLeftD2) {
    // .. your code here ..
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.