bboybeatle
bboybeatle

Reputation: 567

Repeating function after variable changes in jQuery

I want 4 text elements to appear, one after the other, every time a button is clicked. Here is the code I've used to implement that...

$('.btn').click(function(){
    $('.text').css({ 'opacity': '0' });

    function loadText(){
        var textNo = 1;

        function nextText(){    
            $('.text'+textNo).animate({ 'opacity': '1' }, 400);
            textNo += 1;
        }

        if (textNo <= 4){
            nextText(); 
        };  
    }   

    setTimeout(loadText, 300);
});

I want the nextText() function to repeat 4 times, although calling it again doesn't seem to have any effect. Have I missed something obvious here?

You can see it here for a limited time: http://thetally.efinancialnews.com/tallyassets/ceo-survey/index.html

I now realise the problem, partially. When nextText is called there is nothing inside that function to run it again. Can you put a call to a function within a function?

Upvotes: 1

Views: 156

Answers (4)

lshettyl
lshettyl

Reputation: 8181

Another version with setTimeout, but slighly modified code with no nextText() which has been (kind of) replaced by the animation callback. As everyone else already said, move var textNo = 1; outside the loadText().

$('.btn').click(function() {
    $('.text').css({ opacity: 0});
    var textNo = 1, timer;

    function loadText() {
        $('.text' + textNo).animate({
            opacity: 1
        }, 400, function() {
            if ( textNo++ <= 4) {
                loadText();
            } else {
                clearTimeout(timer);
            }
        });
    }

    timer = setTimeout(loadText, 300);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text text1">t1</div>
<div class="text text2">t2</div>
<div class="text text3">t3</div>
<div class="text text4">t4</div>
<button class="btn">Button</button>

Upvotes: 0

Bryan Poor
Bryan Poor

Reputation: 1

loadText is not available to setTimeout, it being contained within the "click" function. You can simply move the loadText function outside of the click definition, as below.

$('.btn').click(function() {
    $('.text').css({
        'opacity': '0'
    });
    setTimeout(loadText, 300);
});

function loadText() {
    var textNo = 1;

    function nextText() {
        $('.text' + textNo).animate({
            'opacity': '1'
        }, 400);
        textNo += 1;
    }
    if (textNo <= 4) {
        nextText();
    };
}

Upvotes: 0

Satpal
Satpal

Reputation: 133453

Use setInterval to call function repeatedly and move textNo so that its incremented value accessible in subsequent call.

Always cancel function from running repeatedly using clearInterval once condition is fulfilled

Use

$('.btn').click(function() {
    $('.text').css({
        'opacity': '0'
    });

    //Move the variable outside
    var textNo = 1;

    function loadText() {
        function nextText() {
            $('.text' + textNo).animate({
                'opacity': '1'
            }, 400);
            textNo++;
        }
        if (textNo <= 4) {
            nextText();
        } else {
            //Cancels repeated action which was set up using setInterval
            clearInterval(interval);
        }
    }

    //Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function. 
    var interval = setInterval(loadText, 300);
});

Upvotes: 2

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85653

You need to use setInterval method instead of setTimeout method. So replace this:

setTimeout(loadText, 300);

With this:

setInterval(loadText, 300);

Upvotes: 2

Related Questions