【问题标题】:Keeping a timer consistent after multiple refreshes in Javascript在Javascript中多次刷新后保持计时器一致
【发布时间】:2015-10-13 10:51:35
【问题描述】:

我有一个倒数计时器,当我快速按 f5 时,计时器会冻结。 我猜这是因为页面在 setInterval 之前重新加载。 我正在寻找一种方法来重新加载页面,同时保持计时器运行发生的事情是页面在 setInterval 甚至可以完成之前重新加载

<h3 style="color:#000000" align="center">
         Time Remaining : <span id='timer'></span>
         </h3>

<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<script>

//define your time in second
    var c = localStorage.getItem("timer");
    if(c == null)c = 3600;

    var t;
    timedCount();

    function timedCount()
    {

        var hours = parseInt( c / 3600 ) % 24;
        var minutes = parseInt( c / 60 ) % 60;
        var seconds = c % 60;

        var result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes <        10 ? "0" + minutes : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);


        $('#timer').html(result);
        if(c == 0 )
        {
            //setConfirmUnload(false);
            //$("#quiz_form").submit();
            window.location="logout.html";
        }
        c = c - 1;
        localStorage.setItem("timer", c);
        t = setTimeout(function()
        {
            timedCount()
        },1000);


    }


</script>

【问题讨论】:

  • 您是否需要计时器在页面重新加载之间持续存在?或者您真正想要实现的目标是什么?

标签: javascript jquery timer


【解决方案1】:

存储计时器启动时计时器应完成的时间,然后从该值中减去当前时间即可得到计时器应完成的时间。 Date 对象适用于此。

HTML

<p id="display">Time Left<p>
<button id="start">Start</button>

Javascript

var start = document.getElementById("start");
var dis = document.getElementById("display");
var finishTime;
var timerLength = 10;
var timeoutID;
dis.innerHTML = "Time Left: " + timerLength;

if(localStorage.getItem('myTime')){
    Update();
}
start.onclick = function () {
    localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
    if (timeoutID != undefined) window.clearTimeout(timeoutID);
    Update();
}

function Update() {
    finishTime = localStorage.getItem('myTime');
    var timeLeft = (finishTime - new Date());
    dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
    timeoutID = window.setTimeout(Update, 100);
}

在此处查看工作示例:JSFiddle

【讨论】:

  • 这是我试图实现的一个很好的例子,但问题是用户可以向前或向后更改计算机的时间以延长或缩短时间
  • 不幸的是,在客户端计算的任何东西总是能够被规避。你只能让他们更难。他们还可以通过浏览器控制台设置本地存储变量,这样他们甚至不需要更改时钟来作弊。最安全的方法是使用服务器端代码,例如 php 或 python。如果你真的需要保留这个 Javascript,你可以考虑让你的代码尽可能地晦涩难懂(他们很难知道如何作弊),并且可能在每次检查时存储最新时间,如果时钟倒退,你知道它们是作弊。
  • 你能解释一下为什么 Math.max(timeLeft/1000,0);返回为 0 最大值?因为 timeLeft/1000 是 0.01,大于 0。我在这里很困惑。
【解决方案2】:

我不确定您希望通过“快速按 F5”实现什么,但每次按下它都会重新加载页面。这是重新加载您的所有 javascript 并重新启动您的计时器。没有办法通过客户端代码重新加载页面来保持计时器运行。此外,由于 javascript 是单线程的,当页面重新加载时,您的计时器函数将被发送到堆栈,一旦处理器准备好,它将等待执行。如果您在计时器之前调用了函数,它们将首先执行。您可以通过将计时器放在服务器上并在页面加载时从客户端获取其进度来完成您尝试做的事情。由于我不知道您的后端是用什么语言编写的,因此我无法为您提供这方面的示例。

【讨论】:

  • 我并没有试图通过快速按 F5 来实现任何目标,我正在制作一个测验应用程序,并且页面中的计时器是一致的,但是通过快速重新加载页面它会冻结计时器。我只是想知道是否有办法解决这个问题,因为用户可以欺骗时间。
  • 不,在客户端没有办法解决这个问题。但是,通过将计时器放在您的服务器上,他们将无法做任何事情来阻碍其进度。它只会在页面上给人一种感觉,即当页面重新加载时计时器正在冻结,但实际上它会在您的服务器上稳定运行。
  • 好的,那我怎么能把时间放到服务器上呢?我正在使用 PHP
  • 网上有很多关于如何在php中设置服务器端定时器的例子。您需要弄清楚的是如何跟踪每一个。可以使用用户会话令牌或您希望使用的任何其他唯一标识符来完成。然后,当您的页面加载时,您还可以加载当前计时器进度(如果它已创建并启动)。初始加载后,您可以使用 javascript 来增加它。如果用户刷新,它会回到服务器获取定时器的当前状态。然后 Javascript 可以从中断的地方继续。
  • 没问题。这听起来像是一个有趣的小项目!享受旅程。
猜你喜欢
  • 2013-09-13
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2020-10-28
  • 2023-03-04
  • 2014-07-18
相关资源
最近更新 更多