JavaScript - 存储页面重新加载的倒计时时间截止日期

时间:2016-05-05 23:51:24

标签: javascript storage countdown

所以在这里我创建了一个10分钟的倒数计时器,以便在按下“开始”按钮时启动。按钮。我想存储这个倒计时,以便当用户离开页面并返回时,倒计时仍将继续。请注意,我不希望倒计时停止,然后继续在页面重新加载时停止,我希望它继续执行指定的截止日期。有什么建议吗?

<html>
<head>

</head>
<body>



    <a id="sendButton" class="button" onclick=" startClock();">START</a>

        <div id="sectionClock">

        <div id="clockdiv">
            <div>
                <span class="hours"></span>
                <div class="smalltext">Hours</div>
            </div>
            <div>
                <span class="minutes"></span>
                <div class="smalltext">Minutes</div>
            </div>
            <div>
                <span class="seconds"></span>
                <div class="smalltext">Seconds</div>
            </div>
        </div>
    </div>

    <script>
function getTimeRemaining(endtime) {
    var t = Date.parse(endtime) - Date.parse(new Date());
    var seconds = Math.floor((t / 1000) % 60);
    var minutes = Math.floor((t / 1000 / 60) % 60);
    var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
    return {
        'total': t,
        'hours': hours,
        'minutes': minutes,
        'seconds': seconds
    };
}
var flag = 0;

function startClock() {


    /************ INITIALIZE CLOCK ************/
    function initializeClock(id, endtime) {

        // If countdown time is 0 then operate
        if(flag==0)
        {
            var clock = document.getElementById(id);
            var hoursSpan = clock.querySelector('.hours');
            var minutesSpan = clock.querySelector('.minutes');
            var secondsSpan = clock.querySelector('.seconds');

        flag=1; 
        }


        function updateClock() {
            var t = getTimeRemaining(endtime);


            hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
            minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
            secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

            if (t.total <= 0) {
                clearInterval(timeinterval);
                flag=0;
            }
        }

        updateClock();
        var timeinterval = setInterval(updateClock, 1000);
    }

    var timeInMinutes = 10;
    var currentTime = Date.parse(new Date());
    var deadline = new Date(currentTime + timeInMinutes*60*1000);
    initializeClock('clockdiv', deadline);

    document.cookie = deadline

    var cookie = document.cookie;

    console.log(cookie);

}

function sendTrack(){
    (function() {

        var trackUrl = document.getElementById("url");    

    }());
}

    </script>

</body>
</html>

2 个答案:

答案 0 :(得分:1)

单击按钮上的

- 设置您正在进行的时间,然后将其存储到localStorage中。这将存储倒计时的开始时间。

var designatedStart_time = //time that the button was clicked;
localStorage.setItem('startTime',designatedStart_time);

然后添加一个在页面加载(或文档就绪)上确定当前时间的函数。这可以与存储的开始时间进行比较,然后可以计算差值并从倒数计时器中移除。然后倒计时可以在新的时间开始。请注意,存储的值将是一个字符串,因此您需要解析它以将时间作为数字。

$(document).ready(function(){
var startTime = localStorage.getItem('designatedStart_time');
var currentTime = //mechanism to get current time;
var remainingTime = startTime - currentTime;
//reset coundown to remainingTime
})

例如,如果您在10:00设置10分钟,并且您在页面上停留1分钟并离开页面,则在两分钟后返回,新的时间将从7:00开始。

这样您就不必存储用户在页面上的时间长度或他们离开的时间 - 它只是当前时间减去指定的开始时间。

答案 1 :(得分:0)

这是FIDDLE

关键是将初始挂钟时间存储在&#34;开始时间&#34;变量而不是计算&#34;截止日期&#34;预先计时,然后将其存储在会话存储中,以防您离开或重新加载页面:

var timeStamp = Date.now(), // Set timeStamp to current wall clock time in ms
    timeDelta;

    // if startTime not set, put current timeStamp in session storage
    // and set startTime to timeStamp
    startTime = startTime || getSetStartTime(timeStamp);

然后,每当您更新显示的时间(并检查定时器是否已完成倒计时)时,通过从开始时间减去当前挂钟时间来设定时间增量(自存储的开始时间起经过的时间):

timeDelta = timeStamp - startTime;

然后,如果增量大于最大倒计时时间,则只显示零时间,否则,将倒数时间显示为总倒计时时间 - 时间增量:

if (timeDelta > timerMaxMS) {
  // ... stuff
  timeElem.value = msToTimeStr(0); // display zero time left
  // ... stuff
  return; // return, ending calling of countdown routine
}
timeElem.value = msToTimeStr(timerMaxMS - timeDelta); // Display time left
requestID = window.requestAnimationFrame(updateTime); // call countdown routine via rAF at next repaint cycle

如果自上次调用更新例程以来的时间暂停,则无所谓,因为每次调用时都会占用挂钟时间,并根据每次正确计算时间增量。挂钟时间,即使已经调用更新逻辑已经过了很多分钟。

就我而言,我使用的是window.requestAnimationFrame()而不是setInterval()。虽然它提供了时间戳参数,但它不是挂钟时间,而是自导航开始以来的时间,因此在重新加载时将重置时间。 rAF更新了浏览器的自然绘制周期,因此是定期更新动态更改UI元素的首选方法。

在getSetStartTime()中,我首先尝试从会话存储中获取开始时间。如果它存在,我将其转换为整数并返回它。如果没有,假设我没有运行计时器或显示计时器已完成,所以我使用timeStamp参数将其设置在会话存储中(将其转换为字符串后)然后返回时间戳:

function getSetStartTime(timeStamp) {
  var startTimeStr = sessionStorage.getItem('startTime');

  if (!startTimeStr) {
    sessionStorage.setItem('startTime', String(timeStamp));
    return timeStamp;
  }
  return parseInt(startTimeStr, 10);
}

还有一个clearStartTime()将startTime变量设置为null并删除&#39; startTime&#39;来自sessionStorage的键/值对。

逻辑使用会话存储在页面重新加载或导航时重新启动倒数计时器,如果它包含开始时间键/值对则返回。如果计时器处于停止状态,并且应该显示零和绿色背景等,则此逻辑仍然可以在updateTime()的第一次(也是唯一一次)运行时反映出来:

if (sessionStorage.getItem('startTime')) {
  startTime = null;
  labelElem.innerText = RUNNING_TEXT;
  requestID = window.requestAnimationFrame(updateTime);
}

JavaScript的:

(function() {
  'use strict';

  var FINISHED_COLOR = '#0f0',
    DEFAULT_COLOR = '#fff',
    RUNNING_TEXT = 'Countdown Time Left:',
    STOPPED_TEXT = 'Countdown Finished!',
    MS_PER_SEC = 1000,
    MS_PER_MIN = MS_PER_SEC * 60,
    timerMaxMS = 2 * MS_PER_MIN,
    startTime,
    requestID = null;

  function getSetStartTime(timeStamp) {
    var startTimeStr = sessionStorage.getItem('startTime');

    if (!startTimeStr) {
      sessionStorage.setItem('startTime', String(timeStamp));
      return timeStamp;
    }
    return parseInt(startTimeStr, 10);
  }

  function clearStartTime() {
    startTime = null;
    sessionStorage.removeItem('startTime');
  }

  function pad(num, digits) {
    return String((num / Math.pow(10, digits)).toFixed(digits)).slice(-digits);
  }

  function msToTimeStr(timeInMS) {
    var secs = Math.floor(timeInMS / MS_PER_SEC) % 60,
      mins = Math.floor(timeInMS / MS_PER_MIN) % 60;

    return pad(mins, 2) + ':' + pad(secs, 2) + '.' + pad(timeInMS % 1000, 3);
  }

  window.addEventListener('load', function() {
    var startElem = document.getElementById('start'),
      clearElem = document.getElementById('clear'),
      timeElem = document.getElementById('time'),
      labelElem = document.getElementById('label'),
      idleText = labelElem.innerText;

    function updateTime() {
      var timeStamp = Date.now(),
        timeDelta;

      startTime = startTime || getSetStartTime(timeStamp);
      timeDelta = timeStamp - startTime;

      if (timeDelta > timerMaxMS) {
        labelElem.innerText = STOPPED_TEXT;
        timeElem.value = msToTimeStr(0);
        timeElem.style.background = FINISHED_COLOR;
        // clearStartTime();
        if (requestID) {
          window.cancelAnimationFrame(requestID);
          requestID = null;
        }
        return;
      }
      timeElem.value = msToTimeStr(timerMaxMS - timeDelta);
      requestID = window.requestAnimationFrame(updateTime);
    }

    clearElem.addEventListener('click', function(event) {
      event.preventDefault();
      if (requestID) {
          window.cancelAnimationFrame(requestID);
          requestID = null;
        }
        labelElem.innerText = idleText;
        timeElem.value = '';
        timeElem.style.background = DEFAULT_COLOR;
                clearStartTime();
        return false;
    });

    startElem.addEventListener('click', function(event) {
      event.preventDefault();
      clearStartTime();
      labelElem.innerText = RUNNING_TEXT;
      timeElem.style.background = DEFAULT_COLOR;
      requestID = window.requestAnimationFrame(updateTime);
      return false;
    }, false);

    if (sessionStorage.getItem('startTime')) {
      startTime = null;
      labelElem.innerText = RUNNING_TEXT;
      requestID = window.requestAnimationFrame(updateTime);
    }
  }, false)
}());

HTML:

<form>
  <fieldset>
    <legend>Timer</legend>
    <p>
      <button id="start">Start Timer</button>
      <button id="clear">Clear Timer</button>
    </p>
    <p>
      <label for="time" id='label'>Timer Not Running</label>
      <input type="text" name="time" id="time" readonly="true" />
    </p>
  </fieldset>
</form>

CSS:

label {
  padding-right: 10px;
  text-align: right;
  display: inline-block;
  width: 150px;
}

input {
  width: 75px;
  height: 20px;
  text-align: right;
  padding-right: 5px;
  font-family: "Courier New";
}