jQuery fnQueue plugin - now with promises
by amindunited
HTML
<!-- html elements to assign fnQueues to -->
<div id="secondfndiv"></div>
<div id="thirdfndiv"></div>
<!-- attach the first function to the document -->
<script>
$(document).fnQueue(
function () { console.log('First function');} , {promise:false}
)
</script>
<!-- attach the second function to the window -->
<script>
$(window).fnQueue(
function(){
console.log('Second function');
}
);
</script>
<!-- attach TWO functions to a div -->
<script>
$('#thirdfndiv').fnQueue('set', {'onDocumentReady':false});
$('#thirdfndiv').fnQueue(
function(){
console.log('third function');
}
);
$('#thirdfndiv').fnQueue(
function(){
console.log('third function a second time');
}
);
</script>
<!-- Create buttons to run each of the attached function sets -->
<button id="runfirst">RUN the functions attached to the 'document'</button><br/>
<button id="runsecond">RUN the functions attached to the 'window'</button><br/>
<button id="runthird">RUN the functions attached to the '#thirdfndiv'</button><br/>
JavaScript
////////////////////////////////////////////////////////////////////////////////////
(function ($) {
//An object to hold the functions of the plugin
var methods = {
//Init adds a given function to a stored array for each given element
init: function (fn, options) {
//If the onDocumentReady property is still true when the document it ready
// run this fnQueue
var self = this;
$(document).ready(function () {
var data = $(this).data('fnQueue');
if (data.onDocumentReady) {
self.fnQueue('run');
}
});
//for each element that was passed to the plugin:
return this.each(function (i, obj) {
//Check if it already has fnQueue data added
// and create data for it if it doesn't
if (!$(this).data('fnQueue')) {
$(this).data('fnQueue', {fnArray: [], qArray: [], afterArray: [], onDocumentReady: true});
}
var data = $(this).data('fnQueue');//get a referance to the stored data
//Push this function into the stored array
data.fnArray.push(fn);
});
},
//Run executes each stored function for each given element
run: function () {
//for each element that was passed to the plugin:
return this.each(function () {
//Get the element's stored data
var data = $(this).data('fnQueue');
if (!data || (!data.fnArray && !data.qArray)) {
return;
}
//then for each function stored...call it
for (var i = 0; i < data.fnArray.length; i++) {
data.fnArray[i].call();
}
//then for each promise function stored...call it
if (data.qArray.length) {
var firstFn = data.qArray.shift();
var fnChain = firstFn.call();
var prevFn = fnChain;
// less than or equal so that it runs one more loop to fire the afterArray:
for (var i = 0; i <= data.qArray.length; i++){
//If this is the last loop ... run the afterArray
if (!data.qArray[i]) {
...