如何确保两个setInterval同时持续

时间:2017-09-16 01:34:22

标签: javascript jquery html setinterval

我有一个带JS动画的简单进度条。每20毫秒,进度条的值增加0.25。因此,完成进度条需要20 * 4 * 100ms = 8秒,如下面的JSFiddle所示。



function updateProgress(currentValue, expectedValue){
    var inProgress = setInterval(function() {
      currentValue = currentValue + 0.25;
      $('#progress-bar').attr('value', currentValue);
      $('#progress-text').text(Math.round(currentValue));
      if (currentValue == expectedValue) clearInterval(inProgress);
    }, 20);
  }


updateProgress(0, 100);

<progress id="progress-bar" value="0" max="100"></progress>
<div><span id="progress-text">0</span>%</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

因此,如果我使用相同的代码并以50%而不是0%开始进度条,则需要20 * 4 * 50ms = 4秒才能完成进度条,如下面的JSFiddle所示。< / p>

&#13;
&#13;
function updateProgress(currentValue, expectedValue){
    var inProgress = setInterval(function() {
      currentValue = currentValue + 0.25;
      $('#progress-bar').attr('value', currentValue);
      $('#progress-text').text(Math.round(currentValue));
      if (currentValue == expectedValue) clearInterval(inProgress);
    }, 20);
  }


updateProgress(50, 100);
&#13;
<progress id="progress-bar" value="50" max="100"></progress>
<div><span id="progress-text">50</span>%</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

我希望函数始终具有相同的执行时间,看起来没有起始值。 例如0到 - &gt; 100:4秒,50至 - > 100也是4秒。

我尝试了这个,但它不起作用:

function updateProgress(currentValue, expectedValue){
  var interval = 4000 / (expectedValue - currentValue) / 4;

  var inProgress = setInterval(function() {
      currentValue = currentValue + 0.25;
      $('#progress-bar').attr('value', currentValue);
      $('#progress-text').text(Math.round(currentValue));
      if (currentValue == expectedValue) clearInterval(inProgress);
  }, interval);
}

updateProgress(50, 100);

1 个答案:

答案 0 :(得分:1)

我认为我会使用requestAnimationFrame,这几乎就是它的设计目标。

&#13;
&#13;
function updateProgress(currentValue, expectedValue){
  var valueDelta = expectedValue - currentValue,
      startTime = performance.now();
      
  nextFrame(startTime);
  
  function nextFrame(time) {
      var value = Math.min(expectedValue, currentValue + valueDelta * (time - startTime) / 4000);
      
      setValue(value);
      
      if (value !== expectedValue) {
          requestAnimationFrame(nextFrame);
      }
  }
  
  function setValue(value) {
      $('#progress-bar').attr('value', value);
      $('#progress-text').text(Math.round(value));
  }
}

updateProgress(50, 100);
&#13;
<progress id="progress-bar" value="50" max="100"></progress>
<div><span id="progress-text">50</span>%</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

无论您选择使用requestAnimationFrame还是setInterval,我认为关键是将动画基于当前时间,而不是假设计时器将按计划调用。

当我运行您的原始代码时,它对我来说很好。我的猜测是问题是当间隔非常小时,计时器没有按计划调用,这将取决于平台。 setInterval在最好的时候并不是非常准确,但对于0到100的全范围,你将依赖于一个10毫秒的计时器,这个计时器足够小,可能会出现问题。