2
\$\begingroup\$

I wrote this jQuery code to animate the opacity (sort of Fadein) of certain elements on my page in consecutive order. It feels very inelegant, though.

(function($) {
     function animateFadin($delayedElement, delayTime) {
        $delayedElement.delay(delayTime).animate({
            opacity: 1
        }, 700);
    }
    $(document).ready(function(){
        animateFadin($('#zone-branding-wrapper'),100);
        animateFadin($('#zone-menu-wrapper'),500);
        animateFadin($('#zone-content-wrapper'),600);
        $(".view-nodequeue-1 a[href]").delay(600).each(function(index) {
            $(this).delay(200*index).animate({
            opacity: 1
        }, 100);
        });
    });
}) (jQuery);

Is there a way to reuse the named function animateFadin inside the each?

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

You have written a simple plugin as it is (see:http://learn.jquery.com/plugins/basic-plugin-creation/).

Firstly I don't think I'd put the document ready stuff inside the plugin. Secondly you should remember that jQuery objects are always based on an array (non matched selectors being a zero length array), so you can always use and return the .each function. As a caveat to that, if you are performing the same task on all elements in the jQuery object (and there isn't data bound to them or any calculations that you need to do on a per object basis) you do not need to use .each.

(function( $ ) {

    $.fn.animateFadin= function(amount) {

        return this.each(function() {
             //this is now an individual element you can manipulate
             this.delay(amount).animate({
                 opacity: 1
                 }, 700);
        });

    };

}( jQuery ));

Or in the simple case:

(function( $ ) {

    $.fn.animateFadin= function(amount) {

        return this.delay(amount).animate({
                 opacity: 1
                 }, 700);
    };

}( jQuery ));

You can now call $('#zone-menu-wrapper').animateFadin(500);

If you understand this then you should be able to use the `.each variant to achieve the delays in a marginally more tidy fashion. What you might want to think about adding though is a callback to the animate function if what you hope to achieve is one element animating after the other.

To do that you would not use each but a simple recursion. Pseudo-code without error/bounds checking:

function chain(this, them) {
    If (!this) return;

    nextThis = them.pop();

    this.delay(whatever).animate({...}, 100, function() {
            chain(nextThis, them);
    });
}

Call this from within the body of animateFadin with the head and [rest] of the jQuery object's object array. What would be nice is to write a plugin to which you pass a function (the action, in your case delay then animate) so that this is reusable behavior. Maybe it already exists?

All code untested and written on my phone, which was harder than I thought! Good luck.

\$\endgroup\$
1
  • \$\begingroup\$ Thx man! I'm going to try all of this tonight. You wrote this on your phone? I tried that the other day, and its quite nightmare-ish, especially the ( , { and ;. Good job though! \$\endgroup\$
    – jeroen
    Commented Aug 22, 2013 at 11:14
2
\$\begingroup\$

I think the best way of animation is CSS. I think the right way is css transitions in your case. Try to add css modificators like .show {opacity:1} or .hide {opacity:0} to your CSS, then add css-transions (like transition:opacity .1s;) to styles of your elements. Use javascript to switch css-modificators of your elements by timers.

In my opinion, CSS-animation uses less CPU and work much faster and retain the logic of views for CSS.

\$\endgroup\$
3
  • \$\begingroup\$ Thx, I know. Maybe I can redo this in css en then use jquery as a fallback using modernizr, but I need support for older IE > caniuse.com/#feat=css-transitions. \$\endgroup\$
    – jeroen
    Commented Aug 21, 2013 at 19:31
  • \$\begingroup\$ In my opinion, best way for older browsers is a graceful degradation. If fadein or fadeout don't work in ie, this is not so bad. Only you decide how best to proceed in your case. \$\endgroup\$ Commented Aug 22, 2013 at 9:34
  • \$\begingroup\$ I agree, but this is quite 'mission critical' :) \$\endgroup\$
    – jeroen
    Commented Aug 22, 2013 at 11:09
2
\$\begingroup\$

One thing that you should do is to remove this function:

$(document).ready(function(){

and move the code inside this to:

(function($) {

like:

(function($) {
    function animateFadin($delayedElement, delayTime) {
        $delayedElement.delay(delayTime).animate({
            opacity: 1
        }, 700);
    }

    animateFadin($('#zone-branding-wrapper'),100);
    animateFadin($('#zone-menu-wrapper'),500);
    animateFadin($('#zone-content-wrapper'),600);
    $(".view-nodequeue-1 a[href]").delay(600).each(function(index) {
        $(this).delay(200*index).animate({
        opacity: 1
    }, 100);
    });
}) (jQuery);

Both are different representations of document.ready()

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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