Search code examples
javascriptjquerystack-overflowchaining

Maximum call stack size exceeded - know why (too many functions) but how to fix it?


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


Solution

  • 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.