警报框出现时,Javascript计时器暂停

时间:2016-12-18 00:56:02

标签: javascript html

我的程序计算用户猜测每个州的正确名称所需的时间。

当用户点击状态所在的星号时,会出现一个输入框,要求用户输入状态名称。

当我按下开始按钮时,计时器开始,但当我选择一个星形来输入答案时,计时器停止。

即使在调用警报后,如何使计时器继续运行?

我的脚本文件

var startButton = document.getElementById("startButton");
var messages = document.getElementById("messages");
var timeId, score;
var count = 0;
states = 50;

startButton.addEventListener("click", startTimer);

function startTimer() {
    startButton.removeEventListener("click", startTimer);
    timeId = window.setInterval(displayNumber, 1000);

}

function displayNumber() {
    count++;
    messages.innerHTML = count;
    if (count == 10) {
        alert("time's up");
        score = (correctChoice - incorrectChoice) * 2;
        alert("your score is " + correctChoice);
        window.clearInterval(timeId);
    }
}

其他脚本文件

var correctChoice = 0;
var incorrectChoice = 0;

document.getElementById("California").addEventListener("click", choice1);

function choice1(e) {
    if (e.type == "click") {
        input = window.prompt("What is the state");
    }
    if (input != "California") {
        alert("wrong answer");
    } else {
        alert("Correct Answer")
        correctChoice++;
        //comment on parent/child node
        var image1 = document.getElementById('California');
        image1.parentNode.removeChild(image1);
        if (correctChoice == 2) {
            alert("you have guessed them all correctly");
            score = (correctChoice - incorrectChoice) * 2;
            alert("your score is " + correctChoice);
        }
    }
}

HTML

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title> MEMORY </title>

    <style type="text/css">
        body {
            background-image: url("usa.jpg");
            background-size: 900px 600px;
            background-repeat: no-repeat;
        }
    </style>
    <body>
        <div style="position: absolute; right: 10px; top: 10pt">
            <input type="button" value="Start!" id="startButton" style="width:80px" />
            <input type="button" value="Reset" id="resetButton" style="width:80px" onClick="window.location.reload()" />

            <h2 id="messages"> </h2>
        </div>
        <img src="state.png" id="California" value="California" width="30px" height="30px" style="position: absolute; left: 130px; top: 200pt" />
    </body>

    <script src="simonSays.js"></script>
    <script src="script.js"></script>
</html>

3 个答案:

答案 0 :(得分:2)

Kieran表示提示会阻止执行,但工作人员或其他线程对您的简单应用程序来说是过度

您需要的是计算时差。增加变量是不可靠的,因为它更多的是一些检查而不是时间计数。

var startTime = new Date(),
    timeLimit = 10; // in seconds

function getElapsed() {
    return (new Date() - startTime) / 1000;
}

function isTimesUp() {
    return getElapsed() >= timeLimit;
}

function promptUser() {
    var input = window.prompt("What is the state");
    // before checking the answer, ensure that there's time left.
    if (isTimesUp()) return timesUp();
    // else check if the answer is correct
}

用户输入答案的时间现在无关紧要,因为需要进行检查以确保在批准答案之前还剩下时间。

概念证明

var startButton = document.getElementById("startButton"),
  testButton = document.getElementById("testButton"),
  resetButton = document.getElementById("resetButton"),
  timerEl = document.getElementById('timer'),
  timeLimit = 10, // in seconds
  startTime,
  timeId;

startButton.addEventListener("click", startTimer);
resetButton.addEventListener("click", reset);
testButton.addEventListener("click", promptUser);

function startTimer() {
  if (timeId) return;
  timerEl.innerHTML = "0";
  timeId = window.setInterval(displayNumber, 500);
  startTime = new Date();
}

function reset() {
  window.clearInterval(timeId);
  timerEl.innerHTML = "-";
  timeId = null;
}

function getElapsed() {
  return (new Date() - startTime) / 1000;
}

function isTimesUp() {
  return getElapsed() >= timeLimit;
}

function timesUp() {
  reset();
  alert("time's up");
  // display score
}

function displayNumber() {
  var elapsed = getElapsed();
  timerEl.innerHTML = Math.floor(elapsed);
  if (elapsed >= timeLimit) {
    timesUp();
  }
}

function promptUser() {
  var input = window.prompt("What is the state");
  if (isTimesUp()) return timesUp();
  // else check if the answer is correct

}
<button type="button" id="startButton">Start</button>
<button type="button" id="resetButton">Reset</button>
<button type="button" id="testButton">Test Answer</button>
<div>Timer: <span id="timer">-</span>
</div>

缺点是计时器看起来像是在后台冻结,但一旦提示关闭,计时器将回到原来的位置,如果它从未冻结,跳过它们之间的任何数字。

此外,您无需刷新页面即可重置,您可以像处理单页应用程序一样处理脚本中的所有内容。

更好的解决方案

使用JavaScript进行交互式应用程序的更好方法是avoid default browser dialog boxes(alert,prompt等)。

来自MDN documentation on alert

  

对话框是模态窗口 - 它们阻止用户访问   程序界面的其余部分,直到对话框关闭。   因此,您不应过度使用任何创建的函数   对话框(或模态窗口)。

而是使用自定义模式,可以进行样式化,例如Bootstrap modalsjQuery's Dialog。这些类型的JavaScript模式不会停止代码执行,因此timer元素仍然会在后台更新。

答案 1 :(得分:0)

输入对话框阻止线程执行,JavaScript在一个线程上运行,因此当出现对话框时,所有执行都被冻结,直到对话框被解除。解决这个问题的方法是将对话框放在另一个线程上,这样一旦它们处于活动状态,它就不会停止执行其他函数。

Introducing HTML 5 Web Workers: Bringing Multi-threading to JavaScript

另一种选择是创建一个不阻塞线程的自定义警报。 Toastr就是一个很好的例子。

答案 2 :(得分:0)

使用this Stackoverflow question

工作人员在页面的后台,您可以在他们离开时与页面进行交互,因此将计时器作为工作人员。

我不经常使用这些,但我认为它会是这样的:

var w = new Worker("the_name_of_your_timer.js");
相关问题