JavaScript - setInterval only running once

2019-05-29 20:27发布

http://jsfiddle.net/689nauny/

setInterval() is only running once... WTF is going on?

SO is asking for more details but providing a JSFiddle is about as descriptive as I can be? I've tried using an anonymous function and now a callback. I just don't get it? :-/

HTML

<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>

<div id="qanda-timer-container">
    <div class="qanda-timer">
        <span id="qanda-time-remaining"></span>
    </div>
</div>

JS

    function intervalFunc(thinkingTime, answerTime)
    {
        jQuery('#qanda-time-remaining').text(''+(thinkingTime - 1));
    }

    function enableTimer(time)
    {
        var intervalID;
        var hasThinkingTime = true;
        var thinkingTime = time;

        var hasAnswerTime = true;
        var answerTime = 10;

        if(hasThinkingTime && hasAnswerTime)
        {
            setInterval( intervalFunc(thinkingTime, answerTime), 1000);
        }

        setTimeout(function(){ 

            clearInterval(intervalID);

        }, time * 1000);
    }

enableTimer(30);

3条回答
冷血范
2楼-- · 2019-05-29 20:48

Here is a working example: http://jsfiddle.net/689nauny/3/

Your issue was partly with scope and in general how you decremented the count down variable

var thinkingTime = undefined;
var answerTime = undefined;
var intervalID = undefined;

function enableTimer(time) {

    var hasThinkingTime = true;
    thinkingTime = time;

    var hasAnswerTime = true;
    answerTime = 10;

    if (hasThinkingTime && hasAnswerTime) {
        intervalID = setInterval(function () {
            thinkingTime -= 1;
            jQuery('#qanda-time-remaining').text('' + (thinkingTime));
        }, 1000);
    }

    setTimeout(function () {

        clearInterval(intervalID);

    }, time * 1000);
}

enableTimer(30);
查看更多
在下西门庆
3楼-- · 2019-05-29 21:00

Your code doesn't work because of this line:

setInterval( intervalFunc(thinkingTime, answerTime), 1000);

Change it into this:

setInterval( function(){
    intervalFunc(thinkingTime, answerTime);
}, 1000);

You need to provide a function to setInterval(), while you are providing undefined.

This is why it doesn't run.

Running code:

function enableTimer(time)
{
    var elem = jQuery('#qanda-time-remaining'), interval = setInterval( function(){

        if(time/1 == time/1 && time) //if(!isNaN(time) && time>0)
        {
            elem.text( time-- );
        }
        else
        {
            clearInterval(interval);
            elem.text(0);
        }
      
    }, 1000);
}

enableTimer(5);
    <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>

    <div id="qanda-timer-container">
        <div class="qanda-timer">
            <span id="qanda-time-remaining"></span>
        </div>
    </div>

I have simplified your code to the extreme and is so much easy to read.

You can set a new parameter to which you provide a function that will run after the time is up:

function enableTimer(time, fn)
{
    var elem = jQuery('#qanda-time-remaining'), interval = setInterval( function(){

        if(time/1 == time/1 && time) //if(!isNaN(time) && time>0)
        {
            elem.text( time-- );
        }
        else
        {
            clearInterval(interval);
            elem.text(0);
            if( fn instanceof Function )//if fn is a function
            {
                fn();//call it
            }
        }
      
    }, 1000);
}

enableTimer(5, function(){ alert('Time\'s up!'); });
    <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>

    <div id="qanda-timer-container">
        <div class="qanda-timer">
            <span id="qanda-time-remaining"></span>
        </div>
    </div>

查看更多
Ridiculous、
4楼-- · 2019-05-29 21:10

You need to wrap the interval handler in a function:

        intervalId = setInterval( function() { intervalFunc(thinkingTime, answerTime) }, 1000);

Your code as posted is calling the function and passing the result to setInterval(). The interval timer isn't running at all!

After you do that, you'll need to fix the problem of maintaining the descending time value. Currently you pass the variable as a parameter and subtract one from it, but you don't update the original variable.

function intervalFunc(thinkingTime, answerTime)
{
    jQuery('#qanda-time-remaining').text(''+(thinkingTime));
}

Then change the setInterval setup:

    intervalId = setInterval( function() { intervalFunc(--thinkingTime, answerTime) }, 1000);

}
查看更多
登录 后发表回答