我可以看到这里提出了几个类似的问题,但不幸的是我找不到我期望的答案。 我对编程很陌生,正在尝试 Javascript 进度条。每当进度条超出宽度时,我都会有一个倒计时计数器,但我遇到了问题,当焦点选项卡处于非事件状态时,进度条会暂停,从而使计数器不倒计时。 我想到了使用网络 worker http://www.tutorialspoint.com/html5/html5_web_workers.htm但我无法让它发挥作用。我将不胜感激来到这里的任何形式的帮助。 下面是我的代码。
<!DOCTYPE html>
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/
jquery.min.js">
</script>
<style>
#progressContainer {
position: relative;
width: 97%;
height: 25px;
background-color: #ddd;
margin-bottom: 15px;
}
#progressBar {
position: absolute;
width: 0%;
height: 100%;
background-color: #A9A9A9;
}
#container{
width: 200px;
height: 200px;
border: 1px solid black;
padding: 10px
}
</style>
<script>
$(document).ready(function(){
$("#countDownBtn").click(function(){
var cdNumber = $("#countDownId").val();
var id = setInterval(frame, 100);
var elem = document.getElementById("progressBar");
var progressBarWidth = 101;
function frame() {
if (progressBarWidth === 0) {
clearInterval(id);
cdNumber--;
$("#countDownId").val(cdNumber);
console.log(cdNumber);
if (cdNumber === 0) {
clearInterval(id);
}
else {
elem.style.width = '100%';
progressBarWidth = 100;
//alert("Hi");
}
}
else {
progressBarWidth--;
elem.style.width = progressBarWidth + '%';
}
}
});
});
</script>
</head>
<body>
<div id="container">
<div>
<input type="text" id="countDownId" value="">
<button id="countDownBtn" class="btn">Click</button>
</div><br>
<div id="progressContainer">
<div id="progressBar"></div>
</div>
</div>
</body>
最佳答案
当依赖某个区间的精度时,你总会遇到这样的问题;甚至requestAnimationFrame
。它们并不精确。
更好的方法(不仅在这种情况下,而且几乎每次你都必须随着时间的推移转换一个值)是保存 startTime 并计算间隔中耗时(如 @ Nosyara 已经建议过)。
当处理缩放因子和/或暂停这些东西时,事情可能会再次变得困惑。这是用于此任务的实用程序:
// The basic concept of this "Clock" is a linear equation over Date.now()
// plus the logic to make this equation pausable.
// therefore it's completely independant of **any** interval; it's just math.
function Clock(v){
var p=true,m=1,b=+v||0,n=Clock.now;
return Object.assign(Object.create(Clock.prototype),{
// getter() / setter(value)
// I don't use real getter and setter, because this syntax
// allows/implements method-chaining
value(v){return arguments.length?(b=(+v||0)-(!p&&m*n()),this):b+(!p&&m*n())},
speed(v){return arguments.length?(v=+v||0,p||v===m||(b+=n()*(m-v)),m=v,this):m},
paused(v){return arguments.length?(((v=!!v)===p)||(b+=n()*((p=v)?m:-m)),this):p},
});
}
Object.assign(Clock.prototype,{
valueOf(){return this.value()},
//aliases for setting the paused() state; doesn't matter if you call them repeatedly.
start(){return this.paused(false)},
stop(){return this.paused(true)},
});
Clock.now=Date.now; //the function used for timing
//Clock.now=performance&&performance.now?performance.now.bind(performance):Date.now;
现在看你的代码:
$(function(){
function frame(){
//yes, countDown get's converted to Number
var value = Math.max(0, countDown);
var count = Math.ceil(value);
var progress = value % 1;
$progressBar.width( progress * 100 + "%" );
//so that I don't update $countDown.val() on every frame, but only if necessary
//on the other hand, it wouldn't be that bad.
if(count !== lastCount) $countDown.val( lastCount = count );
//either stop the countDown or request the next frame.
if(value > 0) requestAnimationFrame(frame);
else countDown.stop();
}
//create a Clock and set speed. Clock is paused by default.
var countDown = Clock().speed( -1 / 10000/*ms*/ );
var $progressBar = $("#progressBar");
var $countDown = $("#countDownId");
var lastCount;
$("#countDownBtn").click(function(){
//if !countDown.paused() then there already is a pending `requestAnimationFrame(frame)`
//from the last call of frame()
if(countDown.paused()) requestAnimationFrame(frame);
countDown.value( $countDown.val() ).start();
});
})
关于javascript - 当选项卡处于非事件状态时,如何使进度条的 setInterval 起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38361954/