Hide a DIV after 5 seconds or when the user clicks the close link

10,602

Solution 1

Try this:

$("#message").fadeIn('slow').delay(5000).fadeOut('slow');

$('#message a.close-notify').click(function () {
    $('#message').stop().fadeOut('slow', removeMessageLayer);
    $('#messageContainer').text();
    return false;
});

Demo: http://jsfiddle.net/xSRk8/15/

The reason why clicking the X to close stopped working when you added the automatic fade is that jQuery queues up animation methods, so in your click handler where you tried to fadeOut() the element that fade out was added to the queue after the delay. If you call .stop() it cancels any existing queued effects so you can do the fadeOut() immediately.

Also your removeMessageLayer() function wasn't actually removing the message element at all - you just thought it was gone because it had faded out. Your code

$('body').remove('#message');

...says to remove the body element if it matches the selector passed to remove(), which of course it never would. You need $('#message').remove();, and you don't need to test whether the message element exists first because jQuery essentially ignores the .remove() if called on an empty jQuery object. So use this:

function removeMessageLayer() {
    $('#message').remove();
}

Solution 2

The code will be (tested )

$("#message").fadeIn('slow').delay(5000).fadeOut('slow'); // display message div
$('#message-close').click(function () {   // click close button
$('#message').stop().fadeOut('slow');

 return false;
});

$(document).on('keydown', function(e) {

if (e.keyCode === 27) {
   $('#message').stop().fadeOut('slow'); // close div when Esc key is pressed
      }
  });
});

Solution 3

$(body).on('click','#message a.close-notify',function () {
    $('#message').fadeOut('slow');
    $('#messageContainer').text();
    removeMessageLayer();
    return false;
});

because it is a dynamically created element, best practice says the click event should be delegated.

    $("#message").fadeIn('slow',function() {
        $(this).delay(5000).fadeOut('slow');
    });

This will give you your five second delay based on the successful creation of the message.

Solution 4

Probably not the cleanest, but you could add a setTimeout call at the end of your displayMessage function.

    timeout = setTimeout(function() {
        $('#message').fadeOut('slow');
        $('#messageContainer').text();
        removeMessageLayer();
        return false;
    }, 5000);

And then in your click handler, call clearTimeout(timeout) to cancel the timeout.

I've updated your fiddle with this. Seems to work.

UPDATE: the code isn't clean -- I repeated some things. But I'll leave the clean up as a future exercise. :)

Share:
10,602
Andy Evans
Author by

Andy Evans

old school developer trying to learn the new school.

Updated on August 22, 2022

Comments

  • Andy Evans
    Andy Evans over 1 year

    For reference, please see the jsFiddle link here. Here's a short script that displays a stackoverflow-style popup message. What I want to do is give the user the option of either letting the message go away on it's own after 5 seconds or to dismiss the message by clicking the 'X' on the right side of the message dialog.

    I've tried to add a delay:

    $("#message").fadeIn('slow').delay(5000).queue(function() {
        $('#message').fadeOut('slow');
    });
    

    Which will work, but then the onClick event on the 'X' link to close the message dialog won't fire.

    Any help would be greatly appreciated.

  • nnnnnn
    nnnnnn almost 11 years
    A delegated handler may be more sensible, but you don't need one in this case because the OP's code only called .click() after creating the element in question.
  • DevlshOne
    DevlshOne almost 11 years
    I'm simply trying to promote best practice while answering questions. You're right, it's not NECESSARY but it is preferred and I've edited my answer to reflect that.
  • nnnnnn
    nnnnnn almost 11 years
    Note that if using a delegated handler like that, that code should be moved out of the displayMessage() function, otherwise it'll bind additional handlers every time a message is displayed.
  • DevlshOne
    DevlshOne almost 11 years
    Would you be happier if I just deleted my answer?
  • Andy Evans
    Andy Evans almost 11 years
    That was it! Thanks!
  • nnnnnn
    nnnnnn almost 11 years
    Sorry. No, I think a delegated handler is a fine alternative here.