Skip to content

Instantly share code, notes, and snippets.

@aklump
Last active December 25, 2015 23:29
Show Gist options
  • Save aklump/7057225 to your computer and use it in GitHub Desktop.
Save aklump/7057225 to your computer and use it in GitHub Desktop.
A jQuery Plugin to fade in multiple DOM elements in step-wise succession.
/**
* A jQuery Plugin to fade in multiple DOM elements in step-wise succession.
*
* @param bool|object options
* A boolean value will be interpreted as {start: [value]}.
* An object with these properties:
* - speed int How fast to reveal the step in seconds. Each element may also
control it's individual speed with the attribute data-speed.
* - delay int Defaults to 0. How many seconds between the end of one step and
the start of the next. You may also use data-delay for element specific
delay.
* - start boolean Trigger the queue start fading in immediately; if you set
this to false you may later call $().multiFadeIn() to start the queue.
- wait int Defaults to 0. A number of seconds to wait to begin the queue.
The entire process is delayed by this many seconds.
A few convenience points, the following DOM manipulations will occurr when
you call this function. The first, a class will be added to each element with
the step index, e.g. multi-fadein-step-1. Secondly, if the attribute
data-step is not present on the element, it too will be added automatically.
*
* In this first example all elements with class .element-step will be
* registered to the queue and the queue will start immediately. The
* order of the elements is determined by the DOM order, but can be tweaked
* based on the attribute 'data-step'. In other words you may explicitly set
* the order of the steps using data-step="1" and so forth.
*
* First the HTML...
* @code
* <div class="element-step" data-step="2">Second Slide</div>
* <div class="element-step" data-step="1">First Slide</div>
* @endcode
*
* Now the calling JS
* @code
* $('.element-step').multiFadeIn();
* @endcode
*
* In this second example the queue is first loaded, and then later start
* based on some trigger, in this case the clicking of .some-trigger.
* @code
* // load but don't start
* $('.element-step').multiFadeIn(false);
*
* // Start after clicking something
* $('.some-trigger').click(function() {
* $().multiFadeIn();
* });
* @endcode
*
* In this more complex example we're going to load elements which are in an
* incorrect DOM order and who do NOT have data-step attributes on this. By
* calling the function multiple times with the start: false option, we can
* register these steps in the correct order we want them to be revealed.
* Notice that the second call does not contain a false option, so the queue
* starts immediately.
*
* First the HTML...
* @code
* <p>I want this to reveal last, but it appears first in the DOM.</p>
* <div class="element-step">First Slide</div>
* <div class="element-step">Second Slide</div>
* @endcode
*
* @code
* $('.element-step').multiFadeIn(false);
* $('p').multiFadeIn();
* @endcode
*
* @return this
*
* @author Aaron Klump, In the Loft Studios, LLC
* @see http://www.intheloftstudios.com
* @see https://gist.github.com/aklump/7057225
*/
(function($) {
$.fn.multiFadeIn = function(options) {
// allow the passing of false to not start the show
if (typeof options === "boolean") {
options = {
start: options
};
}
var $steps = $(this).not('.multi-fadein-processed');
// Create some defaults, extending them with any options that were provided
var settings = $.extend( {
'speed' : 1000,
'delay' : 0,
'start' : true,
'wait' : 0
}, options);
// Hide all steps
$steps.css('visibility', 'hidden')
// Make sure they all have a data-step attribute for sorting; if not
// they'll get step numbers based on the order in which they come in.
.each(function() {
var $step = $(this);
// Add a data-step attribute if missing
if (typeof $step.attr('data-step') === "undefined") {
$step.attr('data-step', $.fn.multiFadeIn.highest);
}
else {
$.fn.multiFadeIn.highest = Math.max($.fn.multiFadeIn.highest, $step.data('step'));
}
$step.addClass('multi-fadein-step-' + $step.attr('data-step'));
$.fn.multiFadeIn.highest += 1;
});
// Sort the steps by step number
$steps.sort(function (a, b) {
var contentA = parseInt($(a).data('step'), 10);
var contentB = parseInt($(b).data('step'), 10);
return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
});
$.merge($.fn.multiFadeIn.queue, $steps);
if (!settings.start) {
return this;
}
// Setup each step to fade in after n seconds
var delay = settings.wait;
$($.fn.multiFadeIn.queue).each(function() {
var $step = $(this);
// Determine if we have a custom delay for this element in data-delay
if (typeof $step.attr('data-delay') === 'undefined') {
delay += settings.delay;
}
else {
delay += $step.data('delay') * 1;
}
// Determine if we have a custom speed for this element in data-speed
var speed = settings.speed;
if (typeof $step.attr('data-speed') !== "undefined") {
speed = $step.data('speed') * 1;
}
setTimeout(function() {
$step.css('visibility','visible').hide().fadeIn(speed);
}, delay);
delay += speed;
$step.addClass('multi-fadein-processed');
});
return this;
};
// Holds the entire queue as it's built
$.fn.multiFadeIn.queue = [];
$.fn.multiFadeIn.highest = 1;
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment