0
\$\begingroup\$

I'm running the below script on a WordPress powered site. It's very heavy on the animations and uses AJAX to fetch posts and load them into a div.

Three things I wanted to address:

  1. Cleaning up the code so that it runs faster/better

  2. Sometimes the AJAX request doesn't get the next post and either keeps showing the same post, or briefly shows the next post then disappears

  3. The animation bubbles() animates in some divs from off screen, and is closed with the closeAggregator() function. Sometimes the closeAggregator() function doesn't trigger the animations to slide the divs out of view, and instead just fades out. Which is problematic because the next time the bubbles() function is triggered, the divs are already in view, thus: no pretty animation.

I imagine a lot of this is due to the lack of cleanliness/organization in the script. Just hoping someone can help clean this bit up!

//resize feeling font-size if word count is too high
function resizeFeeling(){
    var $quote = $(".feeling");
    var $numWords = $quote.text().split(" ").length;    
    if (($numWords >= 12) && ($numWords < 40)) {
        $quote.find('h1').css({
            'font-size' : '46px',
            'line-height' : '48px'
        });
            $quote.find('h2').css({
            'font-size' : '40px',
            'line-height' : '50px'
        });
    }   

};

//binding for key navigation
var pressedKeys = {};
var wtf = {
    'keydown': function (e) {
        if (pressedKeys[e.which])
            return;
            pressedKeys[e.which] = true;
        var keyCode = e.keyCode || e.which,
                key = {left: 37, right: 39, random: 83};

        switch (keyCode) {
            case key.left:
                        if ($('#post-nav .post-next a').length != 0) {
                            $('#keys .left-arrow').toggleClass('pressed');
                            $('#post-nav .post-next a').click();
                        } else { //if reach the beginning
                            $('#keys .left-arrow').toggleClass('pressed');

                            $('.boots').jrumble({rangeX: 5,rangeY: 0, rangeRot: 0, rumbleEvent: 'custom'});$('.boots').trigger('start_rumble');
                        }
                break;
            case key.right:
                if ($('#post-nav .post-previous a').length != 0) {
                    $('#keys .right-arrow').toggleClass('pressed');
                    $('#post-nav .post-previous a').click();
                } else { //if reach the end
                    $('#keys .right-arrow').toggleClass('pressed');

                    $('.boots').jrumble({rangeX: 5,rangeY: 0, rangeRot: 0, rumbleEvent: 'custom'});$('.boots').trigger('start_rumble');
                }
                break;
            //load a random feeling by pressing the 's' key (ie. shuffle)
            case key.random:
                $('#keys .shuffle').toggleClass('pressed');
                randomizeFeelings();
                break;
        }
    },
    'keyup': function (e) { 
        delete pressedKeys[e.which];
        var keyCode = e.keyCode || e.which,
                key = {left: 37, right: 39, random: 83 };

        switch (keyCode) {
            case key.left:
                $('#keys .left-arrow').toggleClass('pressed');
                $('.boots').trigger('stop_rumble');
                break;
            case key.right:
                $('#keys .right-arrow').toggleClass('pressed');
                $('.boots').trigger('stop_rumble');
                break;
            case key.random:
                $('#keys .shuffle').toggleClass('pressed');
                break;
        }
    }
};

//load up the welcome modal with the appropriate welcome message
function welcome() {    
    //Get the time of day
    var currentTime = new Date().getHours();

    //late
    if (0 <= currentTime&&currentTime < 5) {
        $('#heavyBoots h2').append("Hello my restless insomniac,");
    }
    //morning
    if (5 <= currentTime&&currentTime < 12) {
        $('#heavyBoots h2').append("Yawnnnn; good morning baby,");
    }
    //afternoon
    if (12 <= currentTime&&currentTime < 16) {
        $('#heavyBoots h2').append("Whatcha doin' dear?,");
    }
    //evening
    if (16 <= currentTime&&currentTime < 22) {
        $('#heavyBoots h2').append("Hello there,");
    }
    //late
    if (23 <= currentTime&&currentTime <= 24) {
        $('#heavyBoots h2').append("Hey, isn't it your bedtime?");
    }

    //Get the Day
    var day=new Date().getDay();
    switch (day)
    {
    case 0: //Sunday
      $('#heavyBoots p').append("It's a lazy Sunday.");
      break;
    case 1: //Monday
      $('#heavyBoots h2').html("Fuck Mondays.");
      break;
    case 5: //Friday
      $('#heavyBoots p').append("Also, it's Friday!");
      break;
    default: //Any other day
      $('#heavyBoots h2').append("");
    }

    //fade-in the background & then the welcome modal
    $('#home-bg').fadeIn(500, function(){
        $('#heavyBoots').animate({
            bottom: '50%'
        }, 500, 'easeInOutQuint');
    });

    //click to hide the welcome modal and load the first post (resize text if needed)   
    $('#heavyBoots a').live('click', function(){
        $(this).parent().parent().animate({
            bottom: '-150%'
        }, 500, 'easeInOutQuint', function(){
            $('#home-bg').fadeOut(200);
        });
        resizeFeeling();
        $('#content').delay(1500).fadeIn(600);
        $('.heavy h1').delay(1500).animate({
                left: '0%'
            },200, 'easeOutSine');

            $('.heavy h2').delay(1500).animate({
                right: '0%'
            },200, 'easeOutSine', function() {
                // fade-in bg if there
            $('#custom-bg').fadeIn(500);
            });

        //slide-down date
            setTimeout(function() {
                $('#logo').delay(1000).animate({
                    top: '20px'}, 300, 'easeInOutElastic', function(){
                $('.heavy h3 span').animate({
                top: '0px'
            },200, 'easeOutSine', function() {
                        // Animation complete.
                        $('#keys').animate({bottom: '20px'},300, 'easeInOutElastic');
            });
        });
        }, 1000);

        //call first post, activate feelings & bind keys
        $(document).bind(wtf);
            cycleFeelings();

    });
};

function relationshipAggregator() {
    //Remove current feeling from the view & slide out the keyboard legend
    $('.heavy h1').animate({
        left: '-150%'
        },200, 'easeInBack');

    $('.heavy h2').animate({
        right: '-150%'
        },200, 'easeInBack');

    $('#custom-bg').fadeOut(100);
    $('#content').fadeOut(600, function(){
        $('.heavy h3 span').animate({top: '-40px'});
    });
    $('#keys').animate({bottom: '-55px'},300, 'easeInOutElastic');

    //remove key binding to prevent user from accidentally changing the current feeling
    bubbles();
    $(document).unbind(wtf);
    //close the aggregator, bring back the feeling & rebind the keys
};

function closeAggregator() {
    $('#aggregator-close').animate({
            top: '-100px'
        }, 500, 'easeInOutElastic', function() {
            $('#bubble1').animate({
                left: '-150%'
            }, 1000, 'easeOutBack');

            $('#bubble2').animate({
                    top: '-150%'
            }, 1000, 'easeOutBack');

            $('#bubble3').animate({
                bottom: '-150%'
            }, 1000, 'easeOutBack');

            $('#bubble4').animate({
                bottom: '-150%'
            }, 1000, 'easeOutBack');

            $('#bubble5').animate({
                right: '-150%'
            }, 1000, 'easeOutBack');

            $('#bubble6').animate({
                top: '-150%'
            }, 1000, 'easeOutBack');

            $('#reddit').animate({
                bottom: '-150%'
            }, 1000, 'easeOutBack');
        }); 

    setTimeout( function() {
        $('#aggregator').fadeOut(200);
        $('.heavy h1').animate({
            left: '0%'
            },200, 'easeInBack');

        $('.heavy h2').animate({
            right: '0%'
            },200, 'easeInBack');

        $('#custom-bg').fadeIn(100);
        $('#content').fadeIn(600, function(){
            $('.heavy h3 span').animate({top: '0px'});
        });
        $('#keys').animate({bottom: '20px'},300, 'easeInOutElastic');
    }, 800);
    $(document).bind(wtf);
};

//NUMBERS & STUFF
function relationshipCount() {
    var visitTime = $('#visit_time').val();
    var relationshipTime = $('#relationship_time').val();
    var nextDate = new Date(visitTime+':00:00');
    var totalTime = new Date(relationshipTime);

    $("#visit").countdown({
        date: nextDate, //Counting down to a date
        offset: 1,
        hoursOnly: true,
        onChange: function(e,settings) {

        },
        onComplete: function( event ) {

            $(this).html('Right now');
        },
        leadingZero: true
    });

    $("#relationship").countdown({
        date: totalTime, //Counting up to a date
        offset: 1,
        htmlTemplate: "%{o} %{d}",
        hoursOnly: false,
        onChange: function(e,settings) {

        },
        onComplete: function( event ) {

            $(this).html('this should never complete');
        },
        leadingZero: true,
        direction: 'up'
    });
};

function bubbles(){
    $('#aggregator').fadeIn(200);
        comicScroll();
        $('#bubble1').animate({
            left: '50%'
        }, 1000, 'easeInBack');

        $('#bubble2').animate({
                top: '50%'
        }, 1000, 'easeInBack');

        $('#bubble3').animate({
            bottom: '50%'
        }, 1000, 'easeInBack');

        $('#bubble4').animate({
            bottom: '50%'
        }, 1000, 'easeInBack');

        $('#bubble5').animate({
            right: '50%'
        }, 1000, 'easeInBack');

        $('#bubble6').animate({
            top: '50%'
        }, 1000, 'easeInBack', function() {
            $('#aggregator-close').animate({
                top: '70px'
            }, 500, 'easeInOutElastic');
        });

        $('#reddit').animate({
            bottom: '50%'
        }, 1000, 'easeInBack');

    relationshipCount();
};

//the feeling is requested and loaded via AJAX
function cycleFeelings() {
    //grab the next post link and replace default action with ajax load
    $('#post-nav a').stop().live('click', function(e){
        e.preventDefault();
        //remove the current feeling from the view
        $('.heavy h1').animate({
            left: '-150%'
            },200, 'easeInBack');

            $('.heavy h2').animate({
                right: '-150%'
            },200, 'easeInBack');

        var link = $(this).attr('href');
        $('#custom-bg').fadeOut(100);
        $('#content').fadeOut(600, loadContent);  
      //bring in the loading modal
        $('#load').remove();
        $('body').append('<div id="load"><span><h4>Loading</h4><h5>feelings...</h5></span></div>').fadeIn(100); 
        $('#load').animate({
            top: '50%'
            }, 500, 'easeInOutElastic').fadeIn(400); 
        //load up the feeling div with the new feeling content 
        function loadContent() {  
            $('#content').load(link+' .heavy','',showNewContent())  
        }  
        //animate in the newly loaded feeling
        function showNewContent() {  
            setTimeout(function() {$('#content').fadeIn(600,hideLoader());
                resizeFeeling();
                $('.heavy h1').animate({
                left: '0%'
                },200, 'easeOutSine');

                $('.heavy h2').animate({
                    right: '0%'
                },200, 'easeOutSine', function() {
                        // fade-in bg if there
                        $('#custom-bg').fadeIn(500);                    

                        //slide-down date
                        setTimeout(function() {
                        $('.heavy h3 span').animate({
                    top: '0px'
                    },200, 'easeOutSine');
                    }, 500);    
                    }); 
            }, 1000);
        }
        //function to hide the loading modal
        function hideLoader() {  
            $('#load').animate({
                top: '-150%'
            }, 200, 'easeInBack').fadeOut(200);  
        }  
        return false;
    }).stop();
};

    //random feeling is requested and loaded via AJAX
    //TODO: merge with cycleFeelings() to remove redundancy in ajax request function
    function randomizeFeelings(){  
        //remove the current feeling from the view
        $('.heavy h1').animate({
            left: '-150%'
            },200, 'easeInBack');

            $('.heavy h2').animate({
                right: '-150%'
            },200, 'easeInBack');
        var toLoad = "/random-feeling/?cachebuster=" + Math.floor(Math.random()*10001);  
        $('#custom-bg').fadeOut(100);
        $('#content').fadeOut(600, loadContent);
        //bring in the loading modal  
        $('#load').remove(); 
        $('body').append('<div id="load"><span><h4>Loading</h4><h5>feelings...</h5></span></div>').fadeIn(100); 
        $('#load').animate({
            top: '50%'
            }, 500, 'easeInOutElastic').fadeIn(400);
        //load up the random feeling div with the new feeling content  
        function loadContent() {  
            $('#content').load(toLoad,'',showNewContent())  
        }
        //animate in the newly loaded random feeling
        function showNewContent() {  
            setTimeout(function() {$('#content').fadeIn(600,hideLoader()); 
                resizeFeeling();
                $('.heavy h1').animate({
                    left: '0%'
                    },200, 'easeOutSine');

                    $('.heavy h2').animate({
                        right: '0%'
                    },200, 'easeOutSine', function() {
                        // Animation complete.
                        $('#custom-bg').fadeIn(500);

                        //slide-down date
                        setTimeout(function() {
                        $('.heavy h3 span').animate({
                    top: '0px'
                    },200, 'easeOutSine');
                    }, 500);
                    });
            }, 1000);  
        }  
        //function to hide the loading modal
        function hideLoader() {  
            $('#load').animate({
                top: '-150%'
            }, 200, 'easeInBack').fadeOut(200);  
        }  
        return false;  

  };

//future option to have a physical button run the random feeling function
$('.feelings').click(randomizeFeelings);

//bind relationship aggregator to the click of the logo
$('#logo a').click(relationshipAggregator);

//close the aggregator
$('#aggregator-close a').click(closeAggregator);


/*  --------------------------
        RAGE COMIC MODAL
        --------------------------

        TODO: add/remove the div so it doesn't have to be hard-coded in header
*/

$('#reddit a').click(rageComics);

//bringing in the reddit rage comics modal
function rageComics() {
    //unbinding the key nav for the feelings
    $('#ragebox').fadeIn(200);
    //binding the new key nav for the comics
    $(document).bind(wtf2);
    //initializing the first rage comic from reddit
    nextRage();
};

function closeRage() {
        //reset the count so that the first rage comic is loaded on next opening of the reddit modal
        i = -1;
        //unbind the key nav for the comics
        $(document).unbind(wtf2);
        //fadeout the current rage comic so it's not shown on next opening of the reddit modal
        $('.rage-wrap').fadeOut(400);
        //fadout the reddit rage comic modal completely
        $('#ragebox').fadeOut(200);
        //rebind the key nav for the feelings
    }


//binding for rage comics key navigation
var pressedKeys2 = {};
var wtf2 = {
    'keydown': function (e) {
        if (pressedKeys2[e.which])
            return;
            pressedKeys2[e.which] = true;
        var keyCode = e.keyCode || e.which,
                key = {left: 37, right: 39};

        switch (keyCode) {
            case key.left:
                    prevRage();
                break;
            case key.right:
                    nextRage();
                break;

        }
    },
    'keyup': function (e) { 
        delete pressedKeys2[e.which];
        var keyCode = e.keyCode || e.which,
                key = {left: 37, right: 39};

        switch (keyCode) {
            case key.left:
                //stuff
                break;
            case key.right:
                //stuff
                break;
        }
    }
};




/*  --------------------------
        REDDIT JSON REQUEST
        --------------------------

        TODO: get the image url even if url is to imgur page
*/

//set the count
var i = -1;

//parse the json data
function rage(data) {
    var rageURL = data['data']['children'][i]['data']['url']; //the url
    var rageTitle = data['data']['children'][i]['data']['title']; //the title of the rage comic
    //the error variable
    var rageErr = '<div><h5>Whoops!</h5><h6>'+rageTitle+'</h6><a href="'+rageURL+'" target="_blank">try again in a new tab</a></div>';

    //append the image to the modal window
    $('#comic .rage-wrap').html('<img src="'+rageURL+'" />');
    //if the image loads, fade it in
    $('img').load(function() { 
        $('.rage-wrap').fadeIn(400); comicScroll();
    });
    //if the image fails to load, show the error message of the link & title
    $('img').error(function() { 
        $('#comic').removeClass('comic-loader');
        $('.rage-wrap').html(rageErr).fadeIn(400);
    });

};

//JSON request of the next rage comic
function nextRage() {
    if (i>=-1) {
        //increase the count by 1
        i++;
        //fadeout the current comic
        $('.rage-wrap').fadeOut(400);
        $('#comic').addClass('comic-loader');
        $.ajax({
          type: "GET",
          url: "http://www.reddit.com/r/fffffffuuuuuuuuuuuu/.json",
          dataType: "jsonp",
          jsonp: "jsonp",
          cache: true,
          success: rage //run the data^
      });
    }
};

function prevRage() {
    if (i>0) {
        //decrease the count by 1
        i--;
        //fadeout the current comic
        $('#comic').addClass('comic-loader');
        $('.rage-wrap').fadeOut(400);
        $.ajax({
          type: "GET",
          url: "http://www.reddit.com/r/fffffffuuuuuuuuuuuu/.json",
          dataType: "jsonp",
          jsonp: "jsonp",
          cache: true,
          success: rage //run the data^
      });
    }
};

//binding the previous rage comic button
$('.prev-rage a').click(prevRage);
//binding the next rage comic button
$('.next-rage a').click(nextRage);
//bind closing the modal to the close button
$('#closerage').click(closeRage);


/*  --------------------------
        LOGO & LOVE HOVER STATES
        --------------------------
*/
function hoverStates() {

    //Main Logo
    $('#logo').hover( function () {
      $(this).stop().animate({opacity : 1}, 100);     
  }, function () {  
      $(this).stop().animate({opacity : .6}, 100);       
  });

    //Love Icon (fill up)
    $('#love a').hover( function () {
        $(this).find('span').stop().animate({height:'0'},400, 'easeInSine');
    }, function () {
        $(this).find('span').stop().animate({height:'44px'},400, 'easeOutSine');
    });

    //Aggregator Close
    $('#aggregator-close').hover( function () {
      $(this).stop().animate({opacity : 1}, 100);     
  }, function () {  
      $(this).stop().animate({opacity : .6}, 100);       
  });
};


// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.push(arguments);
  if(this.console) {
    arguments.callee = arguments.callee.caller;
    var newarr = [].slice.call(arguments);
    (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
  }
};

// make it safe to use console.log always
(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
{console.log();return window.console;}catch(err){return window.console={};}})());


(function($) {
    $.fn.prettynumber = function(options) {
        var opts = $.extend({}, $.fn.prettynumber.defaults, options);
        return this.each(function() {
            $this = $(this);
            var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
            var str = $this.html();
            $this.html($this.html().toString().replace(new RegExp("(^\\d{"+($this.html().toString().length%3||-1)+"})(?=\\d{3})"),"$1"+o.delimiter).replace(/(\d{3})(?=\d)/g,"$1"+o.delimiter));
        });
    };
    $.fn.prettynumber.defaults = {
        delimiter       : ','   
    };
})(jQuery);
\$\endgroup\$
  • \$\begingroup\$ This would be much easier to review if it was broken down into bite-sized chunks. Just put an important part of the code here and link to the rest. Or make multiple questions with different parts of the code in it. Hopefully that will help you get some great answers \$\endgroup\$ – James Khoury Dec 4 '11 at 23:47
2
\$\begingroup\$

You should always cache your selectors, even if they're used only once.

For example: var $visit = $("#visit"); etc.

\$\endgroup\$
  • \$\begingroup\$ so for example, just like in the first example, which has: var $quote = $(".feeling"); I should do the same thing inside the rest of my functions? \$\endgroup\$ – ndimatteo Oct 27 '11 at 16:39
  • \$\begingroup\$ Yes, for example, with a quick glance I see you're using $("#heavyBoots h2") seven times. Everytime jQuery has to scan your whole DOM to find that specific selector. If you cache it, that process happens only once. It can give a pretty good performance boost, especially in complex/long DOMs. \$\endgroup\$ – vmasto Oct 27 '11 at 20:58
  • 1
    \$\begingroup\$ Why must he cache it even if they're used only once? \$\endgroup\$ – Some Guy Nov 29 '11 at 13:24
  • \$\begingroup\$ why prefix it with $ though? I don't get why people do that.. I imagine it's just an indicator that it's a jQuery object. But I'm not sure on that. \$\endgroup\$ – bought777 Dec 5 '11 at 5:39
  • \$\begingroup\$ @mmmshuddup That's pretty much why. It's a convention that works for me. \$\endgroup\$ – kojiro Dec 5 '11 at 15:16
1
\$\begingroup\$

I looked at just the first part of your welcome() function:

Firstly You have multiple $('#heavyBoots p').append( type calls, If you need to change it you will have multiple places to alter. I put the greeting /comment in a variable and += (for .append()) or = (for .html()). This is cleaner IMHO.

Also I'd have to ask where you put your else if tool. You had multiple "if" statements that can be combined into one else if. This means when it finds one it doesn't have to evaluate any more of them and it has the added benefit of only needing one test.

There was a redundant default: case in your switch which seemed to append nothing ("")to the page.

function welcome() {
    //Get the time of day
    var currentTime = new Date().getHours();

    var greeting = "";
    var comment = "";

    if (currentTime < 0) {
        greeting = "Current Time is Negative. The World doesn't exist yet.";
    }
    else if (currentTime < 5) {
        //late
        greeting = "Hello my restless insomniac,";
    }
    else if (currentTime < 12) {
        //morning
        greeting = "Yawnnnn; good morning baby,";
    }
    else if (currentTime < 16) {
        //afternoon
        greeting = "Whatcha doin' dear?,";
    }
    else if (currentTime < 22) {
        //evening
        greeting = "Hello there,";
    }
    else if (currentTime <= 24) {
        //late
        greeting = "Hey, isn't it your bedtime?";
    }
    else
    {
        greeting = "The World has ended or someone added more hours in the day.";
    }


    //Get the Day
    var day = new Date().getDay();
    switch (day) {
        case 0:
            //Sunday
            comment = "It's a lazy Sunday.";
            break;
        case 1:
            //Monday
            greeting = "Fuck Mondays.";
            break;
        case 5:
            //Friday
            comment = "Also, it's Friday!";
            break;
    }


    $('#heavyBoots p').append(comment);
    $('#heavyBoots h2').append(greeting);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.