【问题标题】:JavaScript | Difficulties with while-loop and timerJavaScript | while循环和计时器的困难
【发布时间】:2016-06-11 12:56:38
【问题描述】:

我正在开发番茄钟式的计时器。计时器必须能够执行以下操作:

按下“开始”按钮时:

  • 启动 5 秒计时器。当然,时代会改变)
  • 定时器到期后,发送带有开始和结束时间戳的 AJAX 事件
  • 启动 3 秒计时器。
  • 定时器到期后,启动一个新的 5 秒定时器。 (循环步骤 1 到 3 共 4 次)
  • 在第四个循环结束时,启动一个 7 秒计时器。
  • 7 秒定时器到期后,再次启动 5-3 循环。

按下“停止”按钮时:

  • 取消计时器,将其重置回默认状态。

这是我现在的代码:

HTML

<html>
<head>
    <meta charset="UTF-8">
    <title>Pomodoro Test</title>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<div id="test"></div>
<div id="timer">5</div>

<button id="start">Start</button>
<button id="reset">Reset</button>

<div id="startTime"></div>
<div id="endTime"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="functions.js"></script>
</body>
</html>

JavaScript:

var timer = 5;
var flag = 0;
var startTime;
var endTime;
var intervalTimer;

function update() {
  if (timer-- > 0) {
    $("#timer").html(timer); // retrieve value from html
  } else {
    endTime = new Date();
    //alert("Start Time = " + startTime + "\nEnd Time = " + endTime);
    $("#endTime").html("End time: " + endTime.toTimeString());
    resetTimer();


    // TODO: send ajax call to server, sending startTime and endTime
    // so that these can be saved to database

  }
}
function loopingTimer() {
  while(flag === 0) {
    startTime = new Date();
    $("#startTime").html("Start time: " + startTime.toTimeString());
    startTimer();
    i++;
  setTimeout(function() {
    if(i < 5) {
      loopingTimer();
    }
  }, 3001)}};

$("#start").click(function() {
  loopingTimer();
});

$("#reset").click(function() {
    flag = 1;
  });



function startTimer() {
  intervalTimer = window.setInterval(update, 500);
}

function resetTimer() {
  stopTimer();
  timer = 5;
  $("#timer").text(timer);
}

function stopTimer() {
  window.clearInterval(intervalTimer);
}

我发现获得所需的功能非常困难,我已经修改此代码 2 天。我真诚地希望你们能帮助我。

蛋糕。

【问题讨论】:

    标签: javascript jquery ajax timer


    【解决方案1】:

    while 循环在loopingTimer 函数中执行(简化):

    while (userDidntStop) {
        startTimer();
    }
    

    中断条件是用户点击了一个按钮。如果用户在 500 次循环(非常非常短的时间)之后这样做,那么这个循环将创建大约 500 个计时器。最大的问题在这里:避免在循环中运行计时器(或相同的间隔)。

    另一个问题是 startTime 在几乎无限循环中被重置。您可以将 loopingTimer 与 startTimer 合并,因为它们基本上只做一件事,即启动计时器,从而防止

    另外,您使用timer 变量来检查经过的时间。浏览器没有义务提供指定的延迟(至少对于setTimeout,根据MDN documentation。我认为setInterval 也是如此)。因此,为了始终拥有正确的时间,实例化一个新的Date() 会更安全。

    此外,还可以将计时器序列存储在某处(即,在数组中),以便随时修改此序列,并轻松循环。

    根据这些要点,我将编写类似于以下代码的内容。请记住,这是一个插图,它可能不会产生您想要的行为。

    var timeLoop = [5, 3, 5, 3, 5, 3, 5, 3, 7]; // seconds
    var timeIterator = timeLoop.length;
    var startTime;
    var endTime;
    var intervalTimer;
    
    function sendTimer() { // once the timer ends, send it
        // send AJAX request with startTime and endTime here
    }
    
    function updateTimer() { // main timer loop
        var now = Date.now(); // make sure you have the right time
        var diff = endTime - now;
        if (diff <= 0) { // if endTime is past, stop and send the timer
            diff = 0;
            clearInterval(intervalTimer);
            sendTimer();
        }
        // Update the displayed time using diff (ms)
    }
    
    function resetTimer() { // to call on $("#reset").click
        if (endTime > Date.now()) {
            endTime = Date.now();
            updateTimer(); // reset the displayed time, and stop updateTimer
            // note that this will call sendTimer() with the _aborted_ time
        }
    }
    
    function startTimer() { // to call on $("#start").click
        resetTimer();
        // We will loop throught the timeLoop every time we start the timer
        if (timeLoop.length < ++timeIterator) {
            timeIterator = 0;
        }
        startTime = Date.now();
        endTime = startTime + 1000 * timeLoop[timeIterator];
        intervalTimer = setInterval(updateTimer, 500);
    }
    

    【讨论】:

    • 感谢您抽出宝贵时间回答我的问题。我有点超出我的深度 - 我不确定如何更新我的 HTML 中的计时器。我将 startTimer 绑定到一个开始按钮,但是当我单击它时 - 没有任何反应。能否以mm:ss格式显示html上的信息?
    • 如果我不清楚,我很抱歉。这段代码实际上对 HTML 文档没有任何作用,只显示了计时器的用法。相信您可以根据自己的 jQuery 代码更改来更新 HTML 元素。剩余时间(ms)由diff存储在updateTimer中;请参阅 this question 关于时间格式(从秒开始,您必须将 diff 除以 1000)。
    • 太棒了。感谢您的宝贵时间。
    • 如果您想要更多解释,请毫不犹豫地指出此答案或代码的黑暗部分。如果您愿意,我也可能会更新它以提供更有效的示例,尽管要进行的更改与计时器无关。 (如果我在英语中犯了一些错误,我很抱歉。)
    • 你的英语很完美,别担心。我不想利用任何人,也不想让别人做我的“功课”,但我真的在用 JavaScript 苦苦挣扎。我现在没有足够的时间来正确学习 JavaScript(这个项目有点时间限制)。也许,你能给我一个“更有效的样本”吗?一种可以实现所有请求的功能并在 mm:ss 中更新 HTML 计时器的方法?如果问得太多了,我理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多