【问题标题】:Javascript Countdown timer shuffles between two timersJavascript倒数计时器在两个计时器之间洗牌
【发布时间】:2021-09-13 10:45:04
【问题描述】:

我有以下 Javascript 代码

// COUNTDOWN TIMER
function refillTimer(refillTimer){
  var countDownDate = new Date(refillTimer).getTime();
  var x = setInterval(function() {
    var now = new Date().getTime();
    var distance = countDownDate - now;
    var hours = ("0" + Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))).slice(-2);
    var minutes = ("0" + Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60))).slice(-2);
    var seconds = ("0" + Math.floor((distance % (1000 * 60)) / 1000)).slice(-2);
    document.getElementById("refillTimer").innerHTML = hours + ":" + minutes + ":" + seconds;
    if(distance < 0){
      clearInterval(x);
      document.getElementById("refillTimer").innerHTML = "00:00:00";
    }
  }, 1000);
}

// ON SWIPE PERFORM ACTION
async function swipeAction(currentElementObj, swipeType) {
  var cardId = currentElementObj.getAttribute("value");
  var dataString = {
    card: cardId,
    swipe: swipeType
  };
  let response = await new Promise((resolve, reject) => {
    try {
      var xhr = new XMLHttpRequest();
      xhr.open("POST", "processes/swipe.php", true);
      xhr.setRequestHeader("Content-Type", "application/json");
      xhr.responseType = "json";
      xhr.send(JSON.stringify(dataString));
      xhr.onreadystatechange = function () {
        let resObj = xhr.response;
        if(xhr.readyState == 4 && xhr.status == 200 && resObj) {
          if(resObj.action == 'gameover'){
            refillTimer(resObj.nextgameoverTimer);
          }else if(resObj.action == 'killsalloted'){
            refillTimer(resObj.nextkillsallotedTimer);
          }
        }
      };
    }catch(e){
      reject(e.toString());
    }
  });
}

正如您在swipeAction() 函数中看到的那样,我有两个ifelse if 成功条件,我调用计时器。这里的问题是,一旦在一种条件下调用定时器,然后在另一种条件下调用定时器就会相互重叠。这不应该发生。计时器应单独加载。这在技术上意味着每次调用计时器函数或类似的东西时都应该刷新它。请查看下面的 GIF 以了解具体问题。

这里,一个条件调用 12 小时定时器,而另一个调用 24 小时定时器。如上所示,两个计时器相互重叠,而不是仅显示各自的计时器。需要的解决方案是什么?

【问题讨论】:

  • 每次刷卡时都会安装一个新的间隔计时器,因此每秒内会触发多个不同的计时器。确保通过从 refillTimer 返回或将其存储在外部范围或全局变量中来保存计时器 ID (x),并在设置下一个之前将其存储在 clearInterval 中,而不仅仅是在 distance 时低于零。
  • 尝试使refillTimer 更普通,从外部传递区间 ID 和日期对象,因为每次调用函数时都会创建一个新的 inteeval ID 和日期对象。
  • @Amadan 和 Kingbeencent 的代码答案会很容易理解和赞赏

标签: javascript timer xmlhttprequest


【解决方案1】:

return x 放入refillTimer。将let timer 放在swipeAction 的顶部,将refillTimer(...) 都更改为timer = refillTimer(...)。将clearInterval(timer) 放在if(resObj.action...) 上方。

或者,将var x = setInterval(...) 更改为timer = setInterval(...)(没有var;另外,避免将x 作为变量名,特别是如果它具有更大的范围)。将let timer 放在function refillTimer(...) { ... } 前面。将clearInterval(timer) 放在refillTimer 函数的开头。

这些操作中的任何一个都将确保您在安装新的间隔计时器之前清除之前的间隔计时器,因此一次只能运行一个。

【讨论】:

  • 感谢您的努力。但是,您可以直接编辑我的代码以获得答案,而不是那种理论解释。那会更容易理解。
  • 好的,我尝试了另一种效果很好的方法。可以说这是一种解决方法,但效果很好。
猜你喜欢
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多