【问题标题】:JavaScript - store a countdown time deadline for page reloadJavaScript - 存储页面重新加载的倒计时截止日期
【发布时间】:2016-05-05 23:51:24
【问题描述】:

因此,我在这里创建了一个 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>

【问题讨论】:

  • 您应该使用var currentTime = Date.now()var currentTime = new Date().getTime() 而不是var currentTime = Date.parse(new Date())

标签: javascript storage countdown


【解决方案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 分钟设置为 10:00,并且您在页面上停留了 1 分钟,然后离开页面并在两分钟后返回,则新的倒计时时间将从 7:00 开始。

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

【讨论】:

    【解决方案2】:

    这是FIDDLE

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

    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;
    

    那么,如果delta大于最大倒计时时间,则只显示零剩余时间,否则,将倒计时时间显示为总倒计时时间-时间delta:

    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 并从 sessionStorage 中删除“startTime”键/值对。

    Logic 使用会话存储在页面重新加载或导航离开和返回时重新启动倒计时计时器(如果它包含开始时间键/值对)。如果计时器处于停止状态,并且应该显示零和绿色背景等,则此逻辑仍然可以反映在 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";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多