Monday, February 7, 2011

Queuing actions (not effects) to execute after an amount of time.

What I'd like to know is if there is a nice way to queue jQuery functions to execute after a set amount of time. This wouldn't pause the execution of other functions, just the ones following in the chain. Perhaps an example of what I'd envisage it would look like would illustrate:

$('#alert')
    .show()
    .wait(5000)    // <-- this bit
    .hide()
;

I know that it's possible by using timeouts, but it seems like that's a messy way to do it, especially compared to the above example (if it were real).

So, is something like this already built-in to jQuery, and if not, what is the best way to emulate it?

  • You can't do that, and you probably don't want to. While it certainly looks pretty, there is no mechanism in Javascript that will allow you do to that without just looping in "wait" until the time has passed. You could certainly do that but you risk seriously degrading the browser performance and if your timeout is longer than a handful of seconds browsers will show a warning to the user that your javascript seems to be stuck.

    The correct way to do this is with timeouts:

    var el = $('#alert');
    el.show()
    setTimeout(function() { el.hide() }, 5000);
    

    Your other option would be to extend jquery to essentially add an effect for actions you want to delay:

    jQuery.fn.extend({
        delayedHide: function(time) {
            var self = this;
            setTimeout(function() { self.hide(); }, time);
        }
    });
    
    $('#alert')
        .show()
        .delayedHide(5000)
    ;
    

    You could also extend jquery with a method similar to setTimeout:

    jQuery.fn.extend({
        delayThis: function(fn, time, args) {
            var self = this;
            setTimeout(function() { jQuery.fn[fn].apply(self, args); }, time);
        }
    });
    
    $('#alert')
        .show()
        .delayThis('hide', 5000)
    ;
    

    or to call with args pass arguments in an array:

    $('#alert')
        .show()
        .delayThis('css', 5000, [ 'display', 'none' ])
    ;
    
    nickf : Hi Prestaul, thanks for the comment - I've edited the question slightly to clarify that I wouldn't want it to "hang" the browser for that amount of time.
    Aeon : I think this is a perfectly good way to do it :) Vote up!
    From Prestaul
  • The jQuery FxQueues plug-in does just what you need:

    $('#element').fadeOut({
        speed: 'fast',
        preDelay: 5000
    });
    
    From dansays

0 comments:

Post a Comment