我有一个带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;
因此,如果我使用相同的代码并以50%而不是0%开始进度条,则需要20 * 4 * 50ms = 4秒才能完成进度条,如下面的JSFiddle所示。< / p>
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;
我希望函数始终具有相同的执行时间,看起来没有起始值。 例如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);
答案 0 :(得分:1)
我认为我会使用requestAnimationFrame
,这几乎就是它的设计目标。
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;
无论您选择使用requestAnimationFrame
还是setInterval
,我认为关键是将动画基于当前时间,而不是假设计时器将按计划调用。
当我运行您的原始代码时,它对我来说很好。我的猜测是问题是当间隔非常小时,计时器没有按计划调用,这将取决于平台。 setInterval
在最好的时候并不是非常准确,但对于0到100的全范围,你将依赖于一个10毫秒的计时器,这个计时器足够小,可能会出现问题。