9

I am displaying a message box on a website. I would like to be able to have it either fadeout on click or after X seconds. The problem is that the delay() function takes the place over the click() function making it so even if you click close you still have to wait the time.

Here is the jQuery

$(document).ready(function() {    
$(".close-green").click(function () {
        $("#message-green").fadeOut("slow");
    });

    //fade out in 5 seconds if not closed
    $("#message-green").delay(5000).fadeOut("slow");

})

I also set up a simple jsfiddle. To see the problem comment out the delay line http://jsfiddle.net/BandonRandon/VRYBk/1/

Brooke.
  • 3,411
  • 13
  • 46
  • 79
  • possible duplicate of [delay JQuery effects](http://stackoverflow.com/questions/251204/delay-jquery-effects) – swilliams Mar 17 '11 at 22:03
  • @swilliams that's not even close to the same thing. That person wants to know HOW to delay an animation, the OP already knows how but wants to know how to prevent the delay if an event takes place before the delay is finished. – Oscar Godson Mar 17 '11 at 22:04

3 Answers3

24

You should change it to a setTimeout: http://jsfiddle.net/VRYBk/3/

(in the jsfiddle link) I removed your delay line and replaced it with a standard setTimeout like:

setTimeout(function(){
    $("#message-green").fadeOut("slow");
},5000)

As a note of WHY, is because JS is read top to bottom and it'll read your delay before you click and trigger the event. Therefore, even when you click the delay is being run causing all animation to pause.

Oscar Godson
  • 28,084
  • 40
  • 103
  • 191
7

This would be an ideal use for jQuery 1.5's new Deferred objects:

// a deferred object for later processing
var def = $.Deferred();

// resolve the deferred object on click or timeout
$(".close-green").click(def.resolve);
setTimeout(def.resolve, 5000);

// however the deferred object is resolved, start the fade
def.done(function() {
    $(".message-green").fadeOut("slow");
});

Working demo at http://jsfiddle.net/Nyg4y/3/

Note that it doesn't matter that if you press the button the timer still fires - the second call to def.resolve() is ignored.

Alnitak
  • 313,276
  • 69
  • 379
  • 466
  • Thanks, I'm using a slightly older version of the library but if I upgrade to 1.5 I now have something to go off of. – Brooke. Mar 19 '11 at 21:04
1

I fount it the best workaround suggested by Oscar Godson, I somehow added this to it:

if (! $clicked.hasClass("search"))
{
    setTimeout(function()
    {
        jQuery("#result").delay('1500').fadeOut('2800');
    },7000);
}
});

His original suggestion is very useful:

You should change it to a setTimeout: http://jsfiddle.net/VRYBk/3/

(in the jsfiddle link) I removed your delay line and replaced it with a standard setTimeout like:

 setTimeout(function(){
      $("#message-green").fadeOut("slow");
 },5000)

By Oscar Godson,

Peter Manoukian
  • 173
  • 1
  • 13