代码之家  ›  专栏  ›  技术社区  ›  spice

两个给定时间戳的剩余时间百分比javascript

  •  0
  • spice  · 技术社区  · 6 年前

    我有两个 Date() 时间,我试图用它们之间的差异来设置一个进度条的宽度,当时间之间没有更多的差异时,它的宽度从100%缩小到0%,但是我得到了非常奇怪的结果。

    这就是我目前尝试的方法(它在react中被拆分为几个不同的函数,因此我只包括相关的代码):

    首先,我设置目标日期时间,它设置 endDate 在接下来的24小时内(如晚上10点)到达最高峰……

    this.endDate = new Date();
    
    if (this.props.data.end_hr === 0) {
        this.endDate.setHours(24, 0, 0, 0);
    } else {
        this.endDate.setHours(this.props.data.end_hr);
    }
    this.endDate.setMinutes(0);
    this.endDate.setSeconds(0);
    
    this.countdown = setInterval(this.timeRemaining, 1000);
    

    然后在 timeRemaining 函数,每秒触发一次,我得到当前的日期时间并计算它们之间的差异。最后,我要计算出发送到进度条css width属性的百分比…

    let now = new Date().getTime();
    let diff = this.endDate - now;
    
    let percent =
      Math.round(((diff / this.endDate) * 100000000 * 2) / 100) + '%';
    
    this.countdownProgress.style.width = percent;
    

    这个 diff 100%正确,但百分比错误。

    我尝试过各种不同的方法来计算我能想到的百分比,但是没有什么能像预期的那样工作,上面的方法是我能得到的最接近的方法。

    有人能告诉我哪里出错了吗?

    编辑 :@danziger的答案以我想使用的方式实现。这将开始时间设置为晚上10点,结束时间设置为午夜。

    结果证明它工作正常,所以我的代码中必须有其他东西导致了这个问题。再次感谢丹齐格给我展示了光明!

    const progressBar = document.getElementById('progressBar');
    const progressText = document.getElementById('progressText');
    
    const startDate = new Date();
    startDate.setHours(22);
    startDate.setMinutes(0);
    startDate.setSeconds(0);
    
    const endDate = new Date();
    endDate.setHours(24,0,0,0);
    endDate.setMinutes(0);
    endDate.setSeconds(0);
    
    const range = endDate - startDate;
    
    function updateCountdown() {
      const diff = Math.max(0, endDate - new Date());
      
      progressBar.style.width = `${ 100 * diff / range }%`;
      progressText.innerText = `${ `000${ Math.ceil(diff / 1000) }`.slice(-4) } seconds`
      
      if (diff >= 0) {
        requestAnimationFrame(updateCountdown);
      }  
    }
    
    updateCountdown();
    body {
      font-family: monospace;
    }
    
    .progressBar__base {
      position: relative;
      height: 32px;
      border: 3px solid black;
      margin: 0 0 8px;
    }
    
    .progressBar__progress {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      background: blue;
    }
    <div class="progressBar__base">
      <div class="progressBar__progress" id="progressBar"></div>
    </div>
    
    <div id="progressText"></div>
    2 回复  |  直到 6 年前
        1
  •  1
  •   Danziger    6 年前

    你需要分开 diff 在某种范围内,在这种情况下,最初的时间差(即其最大值),而不是 endDate :

    const progressBarDescending = document.getElementById('progressBarDescending');
    const progressBarAscending = document.getElementById('progressBarAscending');
    const progressTextDescending = document.getElementById('progressTextDescending');
    const progressTextAscending = document.getElementById('progressTextAscending');
    
    const startDate = new Date();
    const endDate = new Date(startDate.getTime() + 10000); // + 10 seconds
    const range = endDate - startDate;
    
    function updateCountdown() {
      const diff = Math.max(0, endDate - new Date());
      
      progressBarDescending.style.width = `${ 100 * diff / range }%`;
      progressBarAscending.style.width = `${ 100 - 100 * diff / range }%`;
      
      progressTextDescending.innerText = `${ `000${ Math.ceil(diff / 1000) }`.slice(-4) } seconds left`;
      progressTextAscending.innerText = `${ `000${ Math.floor((range - diff) / 1000) }`.slice(-4) } seconds elapsed`;
      
      if (diff >= 0) {
        requestAnimationFrame(updateCountdown);
      }  
    }
    
    updateCountdown();
    body {
      font-family: monospace;
    }
    
    .progressBar__base {
      position: relative;
      height: 32px;
      border: 3px solid black;
      margin: 16px 0 8px;
    }
    
    .progressBar__progress {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      background: blue;
    }
    <div class="progressBar__base">
      <div class="progressBar__progress" id="progressBarDescending"></div>
    </div>
    
    <div id="progressTextDescending"></div>
    
    <div class="progressBar__base">
      <div class="progressBar__progress" id="progressBarAscending"></div>
    </div>
    
    <div id="progressTextAscending"></div>

    那么,假设您从以下时间开始倒计时: startDate = 5 endDate = 15 所以你的 range = 10 .

    如果要更新 微分 之后 5 几秒钟,就是 diff = endDate - now = endDate - 10 = 5 . 然后, progress = 100 * diff / range = 100 * 5 / 10 , progress = 100 * diff / endDate = 100 * 5 / 15 .

        2
  •  3
  •   Justin Jasmann    6 年前

    我认为你的问题是你没有定义 startTime 作为参考而使用 now .

    如果你有 开始时间 你会这样做:

    let now = new Date().getTime();
    let totalTime = endTime - startTime;
    let progress = now - startTime;
    let percentage = (progress / totalTime) * 100;
    

    我不确定你自己的计算能得到什么价值。