1

On my page I have a simple piece of code based on nested functions, which helps me to show one elements after another in right order:

        var fade = 700;
        $('#s2icon-center').fadeIn(fade, function() {
            $('#s2icon-1').fadeIn(fade, function() {
                $('#s2icon-3, #s2icon-9').fadeIn(fade, function() {
                    $('#s2icon-6, #s2icon-11, #s2icon-17').fadeIn(fade, function() {
                        $('#s2icon-5, #s2icon-14, #s2icon-19').fadeIn(fade, function() {
                            $('#s2icon-8, #s2icon-13, #s2icon-22').fadeIn(fade, function() {
                                $('#s2icon-2, #s2icon-16, #s2icon-21').fadeIn(fade, function() {
                                    $('#s2icon-4, #s2icon-10, #s2icon-24').fadeIn(fade, function() {
                                        $('#s2icon-7, #s2icon-12, #s2icon-18').fadeIn(fade, function() {
                                            $('#s2icon-15, #s2icon-20').fadeIn(fade, function() {
                                                $('#s2icon-23').fadeIn(fade);
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });

But in my opinion, because of using too many functions in one place, page is getting laggy and I get an error in console: 'Uncaught RangeError: Maximum call stack size exceeded'

Now my question to you guys is, how (in most easy way) can I get same effect but more productive?

Thanks in advance!

------------- EDIT

Here how it's should look: Codepen Full view

And the code is right here: Codepen DEMO

3
  • please create jsFiddle for your code Commented Mar 24, 2014 at 9:57
  • Done, I'he add codepen demo to my post :) Commented Mar 24, 2014 at 10:55
  • Wow, that looks like a bug in jQuery. Commented Mar 24, 2014 at 11:06

2 Answers 2

2

What you seem to have a problem with is the animation callback:

Complete Function

If supplied, the complete callback function is fired once the animation is complete. This can be useful for stringing different animations together in sequence. The callback is not sent any arguments, but this is set to the DOM element being animated. If multiple elements are animated, the callback is executed once per matched element, not once for the animation as a whole.

That's not what you want. Instead, use promise, which should also prevent the stack overflow.

var fade = 700;
$('#s2icon-center').fadeIn(fade).promise().then(function() {
    return $('#s2icon-1').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-3, #s2icon-9').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-6, #s2icon-11, #s2icon-17').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-5, #s2icon-14, #s2icon-19').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-8, #s2icon-13, #s2icon-22').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-2, #s2icon-16, #s2icon-21').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-4, #s2icon-10, #s2icon-24').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-7, #s2icon-12, #s2icon-18').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-15, #s2icon-20').fadeIn(fade).promise();
}).then(function() {   
    return $('#s2icon-23').fadeIn(fade).promise();
}).then(function() {   
    console.log("all finished");
});
Sign up to request clarification or add additional context in comments.

2 Comments

I get it. Then I have to read about those promises (I will be honest, I don't know them yet) because they seem to be quite usefull :) Btw. Do you think this solution is more productive than using a for loop and array (solution above)? What's the recommendation to use often? Thank you
You could (should) concert my solution to use an array as well, to reduce the boilerplate overhead. Not using delay like above but promises will properly chain the actions, asserting they don't overlap even with timing interferences. Honestly, your nested callback code shouldn't have produced a stack overflow as well :-)
1

You can use delay() which delays execution of the next function in chain by a specified amount of time.

var fade = 700;

// ID's of all elements you want to fade
var elems = ["#d1", "#d2", "#d3", "#d4", "#d5"];
// In your case:
// var elems = ['#s2icon-center', '#s2icon-1', '#s2icon-3, #s2icon-9', '#s2icon-6, #s2icon-11, #s2icon-17']; // and so on...

// Loop over all those elements
for (var e = 0; e < elems.length; e += 1) {
    // Get element by it's ID (from the array)
    var element = $(elems[e]);

    // Use .delay() to delay execution of fade by the amount
    // "fade * e", so 0, 700, 1400, ...
    element.delay(fade * e).fadeOut(fade);    
}

(note I've used fadeOut() to keep example clear - you'll need to change it to fadeOut().

DEMO.

4 Comments

Yes, this will work if I have to show elements in order, one after another - 1 > 2 > 3 > 4 > 5 > ... But in this case, I have to show those elements in different order - 1 > 2 > 4 and 9 > 3 and 5 and 7 > ... This should simulate a random fadeIn (but it's not a random each time). And all elements are in a circle - a have to show elements placed in few radius rows. I will try to make some fiddle with this.
As long as you're fading one element at a time, it's only a matter of correctly specifying elems array. In your case it would be something like: ['#s2icon-center', '#s2icon-1', '#s2icon-3, #s2icon-9', ...]. Then, of course, in a loop you'd not use ID's but this selectors. I've updated my answer.
I've add a demo and my full code on my first post. You can check it what I have to achieve :) Thanks for your help
omg.. I'm so dumb.. ^^, Yes, it's exactly that what I was looking for.. And all I needed to do was put few ID elems into one array position in your previous code! Thank you very much - I will be wiser from now on :)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.