Sunday, November 15, 2009

ShowSlow - A jQuery plugin for displaying elements in order, one by one with a delay

Recently I needed the functionality for displaying some hidden divs, in order, one by one, and with a timed-delay between each one.

Thus I wrote this jQuery plugin that does infact this (demo):

/*
 * ShowSlow v1.1 - jQuery plugin
 * 
 *  Copyright (c) 2009-2010 Andreas Grech
 *
 *  Dual licensed under the MIT and GPL licenses:
 *    http://www.opensource.org/licenses/mit-license.php
 *    http://www.gnu.org/licenses/gpl.html
 *
 * http://blog.dreasgrech.com
 */

(function($) {
    $.fn.showSlow = function(options) {
        var opts = $.extend({}, $.fn.showSlow.defaults, options),
        elementCounter = 0,
        $elements = this,
        isStopped = 0,
        isPaused = 0,
        callbackExecuted = 0,
        executeCallback = function(val) {
            if (typeof opts.callback == "function") {
                callbackExecuted = 1;
                opts.callback(getValues());
            }
        },
        getValues = function() {
            return {
                elementsDone: elementCounter
            };
        },
        showNextDiv = function($element) {
            if (isPaused || isStopped) {
                return;
            }
            if (!$element.length) {
                executeCallback();
                return;
            }
            $element.slideDown(opts.slideTime, function() {
                setTimeout(function() {
                    showNextDiv($elements.eq(elementCounter++));
                },
                opts.displayTime);
            });
        };

        return {
            start: function() {
                if (isStopped || elementCounter < $elements.length) {
                    $elements.css("display", "none");
                    elementCounter = 0;
                } else if (isPaused) {
                    elementCounter -= 1;
                }
                isStopped = 0;
                isPaused = 0;
                callbackExecuted = 0;
                showNextDiv($elements.eq(elementCounter++));
            },
            stop: function() {
                isStopped = 1;
                if (!callbackExecuted) {
                    executeCallback();
                }
                return elementCounter; //return the number of elements displayed before stopped
            },
            pause: function() {
                isPaused = 1;
            }
        };
    };

    $.fn.showSlow.defaults = {
        slideTime: 1000,
        displayTime: 500
    };
})(jQuery);