.mouseleave() with .delay() working together
Asked Answered
G

3

9

I have a list of several 'triggers' (<li>s), each trigger shows a specific div, and each div has a 'close' button.

Now, I want to improve the usability by adding a timer/delay to the opened/visible div so that after 3 or 5 seconds after the user has moved their mouse away from the trigger, the opened/visible div fades out.

The problem I'm having right now, is that whenever I add a function with .mouseleave(), the opened/visible div hides as soon as the mouse leaves the trigger area.

However, if you remove the function, then the div stays visible and you're able to close it by clicking the close button.

Here's a [FIDDLE/DEMO] 1 of my situation.

Any help would be greatly appreciated.

Thanks.

Galvano answered 6/6, 2011 at 17:35 Comment(0)
D
11

@locrizak's answer is right (+1). This is because .delay() defaults to the effects queue, but .hide() with no parameters hides the selected elements without any effect, so the effects queue isn't involved at all.

If you want to hide without any animation, just use setTimeout:

$('.trigger').mouseleave(function() {
    setTimeout(function () {
        $('.copy .wrapper').hide();
    }, 3000);
});

http://jsfiddle.net/mattball/93F3k/


Last edit, I promise

//Show-Hide divs
var current;
$('.trigger').live('mouseenter', function() {    
    var id = current = $(this).data('code');
    $('#' + id).show().siblings().fadeOut();
}).live('mouseleave', function() {
    var id = $(this).data('code');
    current = null;
    setTimeout(function ()
    {
        if (current !== id) $('#' + id).hide(1);
    }, 3000);
});

//Close button
$('.copy .wrapper span').live('click', function() {
    $(this).closest('.wrapper').stop(true, true).fadeOut();
});

Demo: http://jsfiddle.net/mattball/b2ew5/

Deaton answered 6/6, 2011 at 17:42 Comment(15)
Matt, thanks. I used your setTimeout function but it didn't work, although I wasn't sure if I should've put it inside the $('.trigger').hover(function() or outside. Tnx.Galvano
I don't understand your confusion. Did you look at the jsFiddle?Deaton
It almost works 100%. The problem is that if you hover over the next item after having hovered over another one first but the initial wrapper hasn't faded out yet, then both wrappers fade out at the same time, and after that if you hover over any trigger, its corresponding wrapper fades out after a second has passed even if you leave your mouse over the trigger. Thanks.Galvano
Something else. Just hover up and down over all the triggers and you'll see what I mean.Galvano
See my edit, what do you think? Do you want the other .copy .wrapper elements to hide immediately when you hover over a different .trigger? like this: jsfiddle.net/mattball/T6YUp/1Deaton
Yes, that's correct Matt. Any other .wrapper that's visible should hide immediately, which is what's happening in your example. However, there are still 2 problems there: 1. Hovering up and down the triggers makes the wrappers disappear after a second after leaving the trigger element. And 2. The Close button doesn't close the the .wrapper. Tnx.Galvano
Let me add that problem #1 happens randomly, you just have to hover up and down and at some point you'll see the .wrapper disappear almost immediately after leaving the .trigger, when it should be 3 seconds after. Tnx again.Galvano
BTW, don't call .click() inside of .hover() since that will rebind the click handler every time.Deaton
Hey Matt, your example worked great! That's exactly what I needed. Thanks a lot for your time and advice. Yeah, now that I look at it I don't see a need to call .click() inside the .hover(). Tnx again!Galvano
Hey Matt... is it me or for some reason the wrappers are not hiding at all now in your example? I tried reloading the page too but nothing. o_OGalvano
You're right, it's because I switched from .hover(...) to .live('hover', ...) but didn't write the callback correctly. I'm such a dunce! Anyway, it's fixed now, see the edit.Deaton
Absolutely perfect! Tnx again Matt :)Galvano
Hey Matt, you're going to kill me ^_^, but I there's a small problem: again, if you hover in and out real fast and several times over the triggers, and then stop and simply hover over any trigger, the wrapper appears but it then hides even if your mouse is over a trigger. Amigo Matt, you've invested a lot of time on this already, if you don't want to mess around with this anymore, no worries, all's cool, I totally understand. I wish I could be of more help than just troubleshooting, but as you can see I'm not that proficient at jQuery yet. Tnx again.Galvano
Hm, I don't think I can reproduce the problem, but I'll take a guess. Does this work any better for you? jsfiddle.net/mattball/b2ew5Deaton
Yep, somehow that got rid of the problem. Thank you very much :)Galvano
S
3

you need a duration in the hide:

$('.copy .wrapper').delay(3000).hide('fast');

You can take a look at the docs http://api.jquery.com/delay/

update

is this what your looking for?

$('.trigger').bind("mouseenter" , function() {    
    var id = $(this).attr("data-code"); // Get the data from the hovered element
    $('.copy .wrapper:visible').fadeOut();
    $('#' + id).stop(true, true).show(); // Toggle the correct div    
    //Close button
    $('.copy .wrapper span').click(function() {
        $('.copy .wrapper').fadeOut();
    });
});

Thats it get rid of mouseleave listener

Subulate answered 6/6, 2011 at 17:38 Comment(1)
locrizak, thanks. However, although the visible DIV hides on mouseleave, the 'close' button doesn't work. ie: jsfiddle.net/rzea/8gWJM/3. I did check jQuery's .delay() documentation, but I'm not THAT proficient with JS.Galvano
F
3

Use setTimeout instead of delay.

Working demo: http://jsfiddle.net/J7qTy/

From jQuery delay documentation:

The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.

Friesen answered 6/6, 2011 at 17:45 Comment(1)
marcosfromero, same issue I mentioned in Matt's post. Thanks.Galvano

© 2022 - 2024 — McMap. All rights reserved.