HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Page loader function

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
loaderfunctionpage

Problem

This is the function which I wrote and am currently using in my project. I want to know if there is a better way to write it:

function pageLoader(pageIndex){

            $(".ServicesSectionWrapper,.ServicesSectionWrapper .Selector,.ServicesSection,.JournalSectionWrapper,.JournalSectionWrapper .Selector,.JournalSection,.AboutSectionWrapper,.AboutSectionWrapper .Selector,.AboutSection").hide();

        switch(pageIndex){

        case 1:
        $(".AboutSectionWrapper").fadeIn(400,function(){$("#AboutWrapper").fadeIn(400,function(){$("#ManagerWrapper").fadeIn(400,function(){$("#DeveloperWrapper").fadeIn(400,function(){$("#DesignerWrapper").fadeIn(400,function(){$(".AboutSection").fadeIn(400,function(){$(".AboutSection").addClass("PreLoadRotate")})})})})})});
        break;

        case 2:
        $(".JournalSectionWrapper").fadeIn(400,function(){$("#DateOne").fadeIn(400,function(){$("#DateTwo").fadeIn(400,function(){$("#DateThree").fadeIn(400,function(){$("#DateFour").fadeIn(400,function(){$("#DateFive").fadeIn(400,function(){$("#DateSix").fadeIn(400,function(){$("#DateSeven").fadeIn(400,function(){$("#DateEight").fadeIn(400,function(){$(".JournalSection").fadeIn(400,function(){$(".JournalSection").addClass("PreLoadRotate")})})})})})})})})})});
        break;

        case 3:
        $(".ServicesSectionWrapper").fadeIn(400,function(){$("#AppsWrapper").fadeIn(400,function(){$("#ResponsiveWrapper").fadeIn(400,function(){$("#DigitalWrapper").fadeIn(400,function(){$("#PTRWrapper").fadeIn(400,function(){$(".ServicesSection").fadeIn(400,function(){$(".ServicesSection").addClass("PreLoadRotate")})})})})})});
        break;

        }
    }


And here is the HTML:


 
 
 
 

 


This is a menu (AboutSectionWrapper) which has selectors as you can see. I want to load the menu first and then sequentially load the selectors and finally fade in the menu indicator and add a CSS class which has a transition in it.

It is the same for other cases but for examp

Solution

display:none instead of .hide()

Instead of hiding them like this:

$(".ServicesSectionWrapper,.ServicesSectionWrapper .Selector,.ServicesS...hide()


Add a class common to each (on the HTML) and with that class, use display:none.

.commonClass{display:none}


Sequential Animation

Well, I haven't found anything elegant for sequential jQuery animation (or haven't looked that hard). However, I have made this which executes functions sequentially. It isn't a generic solution for animation, only for this situation.

function animateQueue(q){

    // Get the next item
    var next = q.shift();

    // Remove from the array the selector (or jquery object) and function name
    var obj = $(next.shift());
    var functionName = next.shift();

    // Add in the callback that runs after the animation
    next.push(function(){
       if(!q.length) return; // When done, don't continue
       animateQueue(q);      // otherwise, pass on the queue
    });

    // Run the animation
    jQuery.fn[functionName].apply(obj,next);    
}


All you need to do is write the queue like so:

[selector OR jQuery object, animation function, params except the callback]
animateQueue([
    ['#red','fadeIn',400], 
    ['#blue','fadeIn',400],
    ['#green','fadeIn',400],
    [$('#red'),'fadeOut',400], 
    [$('#blue'),'fadeOut',400],
    [$('#green'),'fadeOut',400]  
]);


Added for a jQuery object since...

Cache objects

to avoid fetching them from the DOM everytime

var red = $('#red');
var blue = $('#blue');
var green = $('#green');

animateQueue([
    [red,'fadeIn',400], 
    [blue,'fadeIn',400],
    [green,'fadeIn',400]
]);


Taking it further

Since the only vital function for the pageLoader with respect to this functionality is selecting what to animate, we can move out everything but the selection. Further, we can store the animation queues into an array, and have pageIndex select them instead. pageIndex should be 0-indexed, so we subtract 1:

var queues = [
  first : [...],
  second : [...],
  third : [...]
];

function animateQueue(q){...}

function pageLoader(pageIndex) {
  animateQueue(queues[pageIndex-1]);
}

Code Snippets

$(".ServicesSectionWrapper,.ServicesSectionWrapper .Selector,.ServicesS...hide()
.commonClass{display:none}
function animateQueue(q){

    // Get the next item
    var next = q.shift();

    // Remove from the array the selector (or jquery object) and function name
    var obj = $(next.shift());
    var functionName = next.shift();

    // Add in the callback that runs after the animation
    next.push(function(){
       if(!q.length) return; // When done, don't continue
       animateQueue(q);      // otherwise, pass on the queue
    });

    // Run the animation
    jQuery.fn[functionName].apply(obj,next);    
}
[selector OR jQuery object, animation function, params except the callback]
animateQueue([
    ['#red','fadeIn',400], 
    ['#blue','fadeIn',400],
    ['#green','fadeIn',400],
    [$('#red'),'fadeOut',400], 
    [$('#blue'),'fadeOut',400],
    [$('#green'),'fadeOut',400]  
]);
var red = $('#red');
var blue = $('#blue');
var green = $('#green');

animateQueue([
    [red,'fadeIn',400], 
    [blue,'fadeIn',400],
    [green,'fadeIn',400]
]);

Context

StackExchange Code Review Q#47615, answer score: 4

Revisions (0)

No revisions yet.