简体   繁体   English

Javascript:重启倒数计时器无法正常工作

[英]Javascript: restarting countdown timer doesn't work as I expect it to

I am making a countdown timer that should be reseting and starting anew every 10 seconds. 我正在制作一个倒数计时器,该计时器应每10秒重设并重新开始。 This is the code I came up with by now: 这是我现在想出的代码:

function count(){
    var end_date = new Date().getTime()+10*1000;
    setInterval(function(){
      var current_date = new Date().getTime();
      var seconds_left = parseInt((end_date - current_date) / 1000);
      document.getElementById("countdown").innerHTML = seconds_left + " seconds ";
    }, 1000);
}

setInterval(function(){count()}, 10*1000);

It is supposed to function as follows: 它的功能如下:
+ I set interval that will restart count() every 10 seconds. +我设置了间隔,该间隔将每10秒重新启动一次count()
+ count() defines end_date - a date 10 seconds from now. + count()定义end_date-从现在起10秒的日期。
+ then count() sets interval that will restart every 1 second. +然后count()设置间隔,每1秒钟重新启动一次。
+ every 1 second seconds_left variable is changed according to how current_date changed with respect to end_date . +每1秒seconds_left变量会根据current_date相对于end_date的更改方式进行更改。
+ as soon as seconds_left becomes 0, setInterval from step 1 fires and starts count() anew. +一旦seconds_left变为0,则从第1步开始触发setInterval并重新开始count()

Which step am I implementing the wrong way? 我执行错误的步骤是哪一步? Do I misunderstand the functioning of setInterval() ? 我会误解setInterval()的功能吗? Here is my JsFiddle: http://jsfiddle.net/sy5stjun/ . 这是我的JsFiddle: http : //jsfiddle.net/sy5stjun/

There are a few things going on, here. 这里发生了一些事情。 You're not specific why you have to set another interval inside your loop, but there are a lot easier ways to accomplish what you're going for. 您并不确定要在循环内设置另一个间隔的原因,但是有很多简单的方法可以完成您要执行的操作。 Another approach follows: 另一种方法如下:

HTML: HTML:

<!-- string concatenation is expensive in any language. 
     Only update what has to change to optimize -->
<h1 id='countdown'><span id="ct"></span> seconds </h1>

JS: JS:

// For one thing, grabbing a new reference to the 
// dom object each interval is wasteful, and could interfere with
// timing, so get it outside your timer, and store it in a var scoped
// appropriately.
var ct = document.getElementById("ct");
// set your start
var ctStart = 10;
// set your counter to the start
var ctDown = ctStart;

var count = function() {
    // decrement your counter
    ctDown = ctDown - 1;
    // update the DOM
    ct.innerHTML = ctDown;
    // if you get to 0, reset your counter
    if(ctDown == 0) { ctDown = ctStart; }
};

// save a reference to the interval, in case you need to cancel it
// Also, you only need to include a reference to the function you're
// trying to call, here. You don't need to wrap it in an anonymous function
var timer = window.setInterval(count, 1000);

My jsFiddle available for tinkering, here: http://jsfiddle.net/21d7rf6s/ 我的jsFiddle可修补,请访问: http : //jsfiddle.net/21d7rf6s/

My guess is that each call is in its own new object and you get multiple instances of itself fighting ever 10 seconds. 我的猜测是,每个调用都在其自己的新对象中,并且您会在10秒钟内遇到多个实例。

Using your approach using date objects here is a possible re-write: 使用您的使用日期对象的方法可以重写:

var tmr = null;
var time;

function bigInterval() {
    clearInterval(tmr);
    time = (new Date()).valueOf() + (10 * 1000);
    smallInterval();
    tmr = setInterval(smallInterval, 500);
}

function smallInterval() {
    var cur = (new Date()).valueOf();
    var seconds_left = parseInt((time - cur) / 1000);
    document.getElementById("countdown").innerHTML = seconds_left + " seconds";
}

bigInterval();
setInterval(bigInterval, 10*1000);

In the above code I've updated the small timer to be 500ms instead of 1000ms as it won't exactly line up with the system clock at 1000 and you get visual jumps in the numbers. 在上面的代码中,我将小型计时器更新为500毫秒(而不是1000毫秒),因为它与1000的系统时钟不完全一致,并且您会看到数字的跳跃。

If exact timing isn't 100% important then here is a possible shorter method: 如果准确的时间安排不是100%重要的,则可以使用以下较短的方法:

var t = 10;

setInterval(function() {
    document.getElementById("countdown").innerHTML = t + " seconds";
    t--;
    if (t <= 0) {
        t = 10;
    }
}, 1000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM