Javascript 如何暂停setInterval()函数?
如何使用Javascript暂停并恢复setInterval()函数 例如,也许我有一个秒表来告诉你你一直在看网页的秒数。有一个“暂停”和“恢复”按钮。clearInterval()在这里不起作用的原因是,如果用户在第40秒和第800毫秒单击“暂停”按钮,当他单击“恢复”按钮时,经过的秒数必须在200毫秒后增加1。如果我在计时器变量上使用clearInterval()函数(单击“暂停”按钮时),然后在计时器变量上再次使用setInterval()函数(单击“恢复”按钮时),则经过的秒数仅在1000毫秒后增加1,这会破坏秒表的准确性Javascript 如何暂停setInterval()函数?,javascript,setinterval,Javascript,Setinterval,如何使用Javascript暂停并恢复setInterval()函数 例如,也许我有一个秒表来告诉你你一直在看网页的秒数。有一个“暂停”和“恢复”按钮。clearInterval()在这里不起作用的原因是,如果用户在第40秒和第800毫秒单击“暂停”按钮,当他单击“恢复”按钮时,经过的秒数必须在200毫秒后增加1。如果我在计时器变量上使用clearInterval()函数(单击“暂停”按钮时),然后在计时器变量上再次使用setInterval()函数(单击“恢复”按钮时),则经过的秒数仅在100
那么我该怎么做呢?您可以使用一个标志来跟踪状态:
var输出=$('h1');
var isPaused=假;
var时间=0;
var t=window.setInterval(函数(){
如果(!i暂停){
时间++;
输出文本(“秒:+时间);
}
}, 1000);
//使用jquery
$('.pause')。在('click',函数(e)上{
e、 预防默认值();
isPaused=真;
});
$('.play')。在('click',函数(e)上{
e、 预防默认值();
isPaused=false;
});代码>
h1{
字体系列:Helvetica、Verdana、无衬线;
字体大小:12px;
}
秒:0
玩
暂停
您不应该在间隔函数中测量时间。相反,只需在计时器启动时节省时间,并在计时器停止/暂停时测量差异。仅使用setInterval更新显示的值。因此,不需要暂停计时器,这样可以获得尽可能高的精度。为什么不使用更简单的方法?添加一个类!
只需添加一个类,告诉间隔不要做任何事情。例如:悬停
var i=0;
this.setInterval(函数(){
if(!$('#counter').hasClass('pauseInterval')){//仅在没有此类'pauseInterval'时运行
console.log('Counting…');
$('#counter').html(i++);//仅用于解释和显示
}否则{
console.log(“停止计数”);
}
}, 500);
/*在本例中,我在mouseover上添加了一个类,并在mouseleave上再次删除它。你当然可以随心所欲*/
$('#计数器')。悬停(函数(){//鼠标输入
$(this.addClass('pauseInterval');
},函数(){//鼠标左键
$(this.removeClass('pauseInterval');
}
);
/*其他例子*/
$(“#暂停区间”)。单击(函数(){
$(“#计数器”).toggleClass('pauseInterval');
});代码>
正文{
背景色:#eee;
字体系列:Calibri、Arial、无衬线字体;
}
#柜台{
宽度:50%;
背景:ddd;
边框:2个实心#009afd;
边界半径:5px;
填充物:5px;
文本对齐:居中;
过渡:.3s;
保证金:0自动;
}
#计数器暂停间隔{
边框颜色:红色;
}
暂停
,而@Jonas Giuro说得对:
您不能暂停setInterval函数,您可以停止它(clearInterval),或者让它运行
另一方面,可以通过以下方式模拟此行为:
你不应该在区间函数中测量时间。相反,只需在计时器启动时节省时间,并在计时器停止/暂停时测量差异。仅使用setInterval更新显示的值
var输出=$('h1');
var isPaused=假;
变量时间=新日期();
var偏移=0;
var t=window.setInterval(函数(){
如果(!i暂停){
var milisec=offset+(新日期()).getTime()-time.getTime();
text(parseInt(毫秒/1000)+“s”+(毫秒%1000));
}
}, 10);
//使用jquery
$('.toggle')。打开('click',函数(e){
e、 预防默认值();
isPaused=!isPaused;
如果(i暂停){
偏移量+=(新日期()).getTime()-time.getTime();
}否则{
时间=新日期();
}
});代码>
h1{
字体系列:Helvetica、Verdana、无衬线;
字体大小:12px;
}
秒:0
切换
我知道此线程很旧,但这可能是另一种解决方案:
var do_this = null;
function y(){
// what you wanna do
}
do_this = setInterval(y, 1000);
function y_start(){
do_this = setInterval(y, 1000);
};
function y_stop(){
do_this = clearInterval(do_this);
};
下面的代码提供了暂停恢复计时器的精确方法
工作原理:
当定时器<强>暂停后恢复/ <强>时,它使用单<代码>超时< /代码>生成一个<强>校正周期< /强>,它将考虑暂停偏移(定时器在周期之间暂停的确切时间)。校正周期结束后,它使用常规的
setInteval
计划以下周期,并正常继续执行周期
这允许暂停/恢复计时器,而不会丢失同步
代码:
函数计时器(\u fn\u回调,\u计时器\u频率){
恢复校正率=2;
让(定时器)状态码(statusCode);;
让定时器时钟参考;
让_time_ellapsed_;//存储ellapsed的总时间
让_time\u pause///存储计时器暂停时的时间
让_time_lastCycle///存储上一个周期的时间
设u为校正周期u;
/**
*在每个时钟周期中执行
*/
const nextCycle=函数(){
//计算deltaTime
让_time_delta_=新日期()-_time_lastCycle;
_时间\上次周期\新日期();
_时间_ellapsed+=_时间_增量;
//如果这是一个修正循环(由暂停引起,
//销毁临时超时并生成最终间隔
如果(_isCorrectionCycle_uu){
clearTimeout(计时器时钟参考);
清除间隔(计时器时钟参考);
_定时器\时钟参考\设置间隔(下一个周期,定时器\频率);
_isCorrectionCycle=假;
}
//执行回调
_fn_callback_uu.apply(timer,[timer]);
};
//初始化定时器
_时间=0;
_时间\上次周期\新日期();
_定时器\状态码\ 1;
_钛
export class IntervalTimer {
private callbackStartTime;
private remaining= 0;
private paused= false;
public timerId = null;
private readonly _callback;
private readonly _delay;
constructor(callback, delay) {
this._callback = callback;
this._delay = delay;
}
pause() {
if (!this.paused) {
this.clear();
this.remaining = new Date().getTime() - this.callbackStartTime;
this.paused = true;
}
}
resume() {
if (this.paused) {
if (this.remaining) {
setTimeout(() => {
this.run();
this.paused = false;
this.start();
}, this.remaining);
} else {
this.paused = false;
this.start();
}
}
}
clear() {
clearInterval(this.timerId);
}
start() {
this.clear();
this.timerId = setInterval(() => {
this.run();
}, this._delay);
}
private run() {
this.callbackStartTime = new Date().getTime();
this._callback();
}
}
const interval = new IntervalTimer(console.log(aaa), 3000);
interval.start();
interval.pause();
interval.resume();
interval.clear();