를 통해 설정된 활성 시간 제한이 실행중인 var t = setTimeout("dosomething()", 5000)
경우
일시 중지하고 다시 시작할 수 있습니까?
현재 시간 초과에 남은 시간을 얻을 수있는 방법이 있습니까?
아니면 변수에 시간 제한이 설정되면 현재 시간을 저장하고 일시 중지하고 지금과 다음의 차이를 얻어야합니까?
를 통해 설정된 활성 시간 제한이 실행중인 var t = setTimeout("dosomething()", 5000)
경우
일시 중지하고 다시 시작할 수 있습니까?
답변:
다음 window.setTimeout
과 같이 포장 할 수 있습니다. 질문에서 제안한 내용과 비슷합니다.
var Timer = function(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= Date.now() - start;
};
this.resume = function() {
start = Date.now();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
};
this.resume();
};
var timer = new Timer(function() {
alert("Done!");
}, 1000);
timer.pause();
// Do some stuff...
timer.resume();
setTimeout()
Internet Explorer <= 9에서는 매개 변수를 추가하는 것이 작동하지 않는다는 점을 제외하면 좋은 추가 기능입니다.
timer.resume(); timer.resume();
하면 두 개의 시간 제한이 병렬로 발생합니다. 그렇기 때문에 이력서의 맨 처음부터 단락을 시작 clearTimeout(timerId)
하거나 if (timerId) return;
단락을 수행 하고 싶을 것 입니다.
var timerId, start, remaining;
클래스 범위 외부에서 remaining = delay;
다시 내부를 추가 하여 매개 변수를 잡아야했습니다. 매력처럼 작동합니다!
if (blah) { ... }
.
이와 같은 것이 트릭을 수행해야합니다.
function Timer(fn, countdown) {
var ident, complete = false;
function _time_diff(date1, date2) {
return date2 ? date2 - date1 : new Date().getTime() - date1;
}
function cancel() {
clearTimeout(ident);
}
function pause() {
clearTimeout(ident);
total_time_run = _time_diff(start_time);
complete = total_time_run >= countdown;
}
function resume() {
ident = complete ? -1 : setTimeout(fn, countdown - total_time_run);
}
var start_time = new Date().getTime();
ident = setTimeout(fn, countdown);
return { cancel: cancel, pause: pause, resume: resume };
}
Tim Downs 답변 의 약간 수정 된 버전입니다 . 그러나 Tim이 내 편집을 롤백 했기 때문에이 문제에 직접 답해야합니다. 내 솔루션을 사용하면 extra arguments
를 세 번째 (3, 4, 5 ...) 매개 변수로 사용하고 타이머를 지울 수 있습니다.
function Timer(callback, delay) {
var args = arguments,
self = this,
timer, start;
this.clear = function () {
clearTimeout(timer);
};
this.pause = function () {
this.clear();
delay -= new Date() - start;
};
this.resume = function () {
start = new Date();
timer = setTimeout(function () {
callback.apply(self, Array.prototype.slice.call(args, 2, args.length));
}, delay);
};
this.resume();
}
Tim이 언급했듯이 추가 매개 변수는에서 사용할 수 IE lt 9
없지만 에서 작동하도록 약간 작업했습니다 oldIE
.
용법: new Timer(Function, Number, arg1, arg2, arg3...)
function callback(foo, bar) {
console.log(foo); // "foo"
console.log(bar); // "bar"
}
var timer = new Timer(callback, 1000, "foo", "bar");
timer.pause();
document.onclick = timer.resume;
"일시 중지"와 "이력서"정말의 맥락에서 많은 이해가되지 않는 setTimeout
A는, 일회성 것. 의미 setInterval
합니까? 그렇다면 일시 중지 할 수 없으며 취소 ( clearInterval
) 만 한 다음 다시 예약 할 수 있습니다. 자세한 내용은 사양 의 타이머 섹션 에 있습니다.
// Setting
var t = setInterval(doSomething, 1000);
// Pausing (which is really stopping)
clearInterval(t);
t = 0;
// Resuming (which is really just setting again)
t = setInterval(doSomething, 1000);
Timeout은 해결책을 찾기에 충분히 쉬웠지만 Interval은 약간 까다로 웠습니다.
이 문제를 해결하기 위해 다음 두 가지 클래스를 생각해 냈습니다.
function PauseableTimeout(func, delay){
this.func = func;
var _now = new Date().getTime();
this.triggerTime = _now + delay;
this.t = window.setTimeout(this.func,delay);
this.paused_timeLeft = 0;
this.getTimeLeft = function(){
var now = new Date();
return this.triggerTime - now;
}
this.pause = function(){
this.paused_timeLeft = this.getTimeLeft();
window.clearTimeout(this.t);
this.t = null;
}
this.resume = function(){
if (this.t == null){
this.t = window.setTimeout(this.func, this.paused_timeLeft);
}
}
this.clearTimeout = function(){ window.clearTimeout(this.t);}
}
function PauseableInterval(func, delay){
this.func = func;
this.delay = delay;
this.triggerSetAt = new Date().getTime();
this.triggerTime = this.triggerSetAt + this.delay;
this.i = window.setInterval(this.func, this.delay);
this.t_restart = null;
this.paused_timeLeft = 0;
this.getTimeLeft = function(){
var now = new Date();
return this.delay - ((now - this.triggerSetAt) % this.delay);
}
this.pause = function(){
this.paused_timeLeft = this.getTimeLeft();
window.clearInterval(this.i);
this.i = null;
}
this.restart = function(sender){
sender.i = window.setInterval(sender.func, sender.delay);
}
this.resume = function(){
if (this.i == null){
this.i = window.setTimeout(this.restart, this.paused_timeLeft, this);
}
}
this.clearInterval = function(){ window.clearInterval(this.i);}
}
다음과 같이 구현할 수 있습니다.
var pt_hey = new PauseableTimeout(function(){
alert("hello");
}, 2000);
window.setTimeout(function(){
pt_hey.pause();
}, 1000);
window.setTimeout("pt_hey.start()", 2000);
이 예제는 2 초 후에 "hey"를 경고하도록 예약 된 일시 중지 가능한 제한 시간 (pt_hey)을 설정합니다. 다른 제한 시간은 1 초 후에 pt_hey를 일시 중지합니다. 세 번째 Timeout은 2 초 후에 pt_hey를 다시 시작합니다. pt_hey는 1 초 동안 실행되고 1 초 동안 일시 중지 된 다음 다시 실행됩니다. pt_hey는 3 초 후에 트리거됩니다.
이제 더 까다로운 간격
var pi_hey = new PauseableInterval(function(){
console.log("hello world");
}, 2000);
window.setTimeout("pi_hey.pause()", 5000);
window.setTimeout("pi_hey.resume()", 6000);
이 예에서는 2 초마다 콘솔에 "hello world"를 작성하도록 일시 중지 가능한 간격 (pi_hey)을 설정합니다. 시간 초과는 5 초 후에 pi_hey를 일시 중지합니다. 또 다른 제한 시간은 6 초 후에 pi_hey를 재개합니다. 따라서 pi_hey는 두 번 트리거되고 1 초 동안 실행되고 1 초 동안 일시 중지되고 1 초 동안 실행 된 다음 2 초마다 트리거를 계속합니다.
clearTimeout () 및 clearInterval ()
pt_hey.clearTimeout();
및 pi_hey.clearInterval();
시간 초과와 간격을 취소 할 수있는 쉬운 방법 역할을합니다.
getTimeLeft ()
pt_hey.getTimeLeft();
그리고 pi_hey.getTimeLeft();
다음 트리거이 예약 될 때까지하는 시간을 밀리 초 단위로 반환합니다.
setInterval
? 나는 단순한 if(!true) return;
것이 트릭을 할 것이라고 생각 합니까, 아니면 내가 틀렸습니까?
진행률 표시 줄을 표시하려면 경과 및 남은 시간을 계산해야했습니다. 받아 들여진 대답을 사용하는 것은 쉽지 않았습니다. 이 작업에서는 'setInterval'이 'setTimeout'보다 낫습니다. 그래서 모든 프로젝트에서 사용할 수있는이 Timer 클래스를 만들었습니다.
https://jsfiddle.net/ashraffayad/t0mmv853/
'use strict';
//Constructor
var Timer = function(cb, delay) {
this.cb = cb;
this.delay = delay;
this.elapsed = 0;
this.remaining = this.delay - self.elapsed;
};
console.log(Timer);
Timer.prototype = function() {
var _start = function(x, y) {
var self = this;
if (self.elapsed < self.delay) {
clearInterval(self.interval);
self.interval = setInterval(function() {
self.elapsed += 50;
self.remaining = self.delay - self.elapsed;
console.log('elapsed: ' + self.elapsed,
'remaining: ' + self.remaining,
'delay: ' + self.delay);
if (self.elapsed >= self.delay) {
clearInterval(self.interval);
self.cb();
}
}, 50);
}
},
_pause = function() {
var self = this;
clearInterval(self.interval);
},
_restart = function() {
var self = this;
self.elapsed = 0;
console.log(self);
clearInterval(self.interval);
self.start();
};
//public member definitions
return {
start: _start,
pause: _pause,
restart: _restart
};
}();
// - - - - - - - - how to use this class
var restartBtn = document.getElementById('restart');
var pauseBtn = document.getElementById('pause');
var startBtn = document.getElementById('start');
var timer = new Timer(function() {
console.log('Done!');
}, 2000);
restartBtn.addEventListener('click', function(e) {
timer.restart();
});
pauseBtn.addEventListener('click', function(e) {
timer.pause();
});
startBtn.addEventListener('click', function(e) {
timer.start();
});
/ 부활
Class-y 구문 설탕을 사용하는 ES6 버전 💋
(약간 수정 : start () 추가)
class Timer {
constructor(callback, delay) {
this.callback = callback
this.remainingTime = delay
this.startTime
this.timerId
}
pause() {
clearTimeout(this.timerId)
this.remainingTime -= new Date() - this.startTime
}
resume() {
this.startTime = new Date()
clearTimeout(this.timerId)
this.timerId = setTimeout(this.callback, this.remainingTime)
}
start() {
this.timerId = setTimeout(this.callback, this.remainingTime)
}
}
// supporting code
const pauseButton = document.getElementById('timer-pause')
const resumeButton = document.getElementById('timer-resume')
const startButton = document.getElementById('timer-start')
const timer = new Timer(() => {
console.log('called');
document.getElementById('change-me').classList.add('wow')
}, 3000)
pauseButton.addEventListener('click', timer.pause.bind(timer))
resumeButton.addEventListener('click', timer.resume.bind(timer))
startButton.addEventListener('click', timer.start.bind(timer))
<!doctype html>
<html>
<head>
<title>Traditional HTML Document. ZZz...</title>
<style type="text/css">
.wow { color: blue; font-family: Tahoma, sans-serif; font-size: 1em; }
</style>
</head>
<body>
<h1>DOM & JavaScript</h1>
<div id="change-me">I'm going to repaint my life, wait and see.</div>
<button id="timer-start">Start!</button>
<button id="timer-pause">Pause!</button>
<button id="timer-resume">Resume!</button>
</body>
</html>
clearTimeout ()을 살펴볼 수 있습니다.
또는 특정 조건이 충족 될 때 설정되는 전역 변수에 따라 일시 중지됩니다. 버튼을 누르는 것처럼.
<button onclick="myBool = true" > pauseTimeout </button>
<script>
var myBool = false;
var t = setTimeout(function() {if (!mybool) {dosomething()}}, 5000);
</script>
이벤트로 구현할 수도 있습니다.
시차를 계산하는 대신 백그라운드에서 계속 실행되는 '틱'이벤트 수신을 시작하고 중지합니다.
var Slideshow = {
_create: function(){
this.timer = window.setInterval(function(){
$(window).trigger('timer:tick'); }, 8000);
},
play: function(){
$(window).bind('timer:tick', function(){
// stuff
});
},
pause: function(){
$(window).unbind('timer:tick');
}
};
어쨌든 jquery를 사용하고 있다면 $ .doTimeout 플러그인을 확인하십시오 . 이 기능은 setTimeout에 비해 크게 개선되었습니다. 여기에는 지정한 단일 문자열 ID로 시간 제한을 추적하고 설정할 때마다 변경되지 않으며 간편한 취소, 폴링 루프 및 디 바운싱을 구현할 수 있습니다. 더. 가장 많이 사용되는 jquery 플러그인 중 하나입니다.
안타깝게도 즉시 일시 중지 / 다시 시작을 지원하지 않습니다. 이를 위해 $ .doTimeout을 래핑하거나 확장해야합니다. 아마도 허용 된 답변과 유사합니다.
슬라이드 쇼와 같은 기능을 위해 setTimeout ()을 일시 중지 할 수 있어야했습니다.
다음은 일시 중지 가능한 타이머를 직접 구현 한 것입니다. 더 나은 일시 중지 (커널의 설명) 및 프로토 타이핑 형식 (Umur Gedik의 설명)과 같이 Tim Down의 답변에 표시된 설명을 통합합니다.
function Timer( callback, delay ) {
/** Get access to this object by value **/
var self = this;
/********************* PROPERTIES *********************/
this.delay = delay;
this.callback = callback;
this.starttime;// = ;
this.timerID = null;
/********************* METHODS *********************/
/**
* Pause
*/
this.pause = function() {
/** If the timer has already been paused, return **/
if ( self.timerID == null ) {
console.log( 'Timer has been paused already.' );
return;
}
/** Pause the timer **/
window.clearTimeout( self.timerID );
self.timerID = null; // this is how we keep track of the timer having beem cleared
/** Calculate the new delay for when we'll resume **/
self.delay = self.starttime + self.delay - new Date().getTime();
console.log( 'Paused the timer. Time left:', self.delay );
}
/**
* Resume
*/
this.resume = function() {
self.starttime = new Date().getTime();
self.timerID = window.setTimeout( self.callback, self.delay );
console.log( 'Resuming the timer. Time left:', self.delay );
}
/********************* CONSTRUCTOR METHOD *********************/
/**
* Private constructor
* Not a language construct.
* Mind var to keep the function private and () to execute it right away.
*/
var __construct = function() {
self.starttime = new Date().getTime();
self.timerID = window.setTimeout( self.callback, self.delay )
}(); /* END __construct */
} /* END Timer */
예:
var timer = new Timer( function(){ console.log( 'hey! this is a timer!' ); }, 10000 );
timer.pause();
코드를 테스트하려면 timer.resume()
및 timer.pause()
몇 번을 사용 하고 남은 시간을 확인하십시오. (본체가 열려 있는지 확인하십시오.)
에서는 setTimeout () 대신에이 객체를 사용하면 쉽게 교체하는 것입니다 timerID = setTimeout( mycallback, 1000)
함께 timer = new Timer( mycallback, 1000 )
. 다음 timer.pause()
과 timer.resume()
을 사용할 수 있습니다.
function delay (ms) { return new Promise(resolve => setTimeout(resolve, s)); }
"async"작업 데모 : site zarsoft.info
최고 평점 답변을 기반으로 한 Typescript 구현
/** Represents the `setTimeout` with an ability to perform pause/resume actions */
export class Timer {
private _start: Date;
private _remaining: number;
private _durationTimeoutId?: NodeJS.Timeout;
private _callback: (...args: any[]) => void;
private _done = false;
get done () {
return this._done;
}
constructor(callback: (...args: any[]) => void, ms = 0) {
this._callback = () => {
callback();
this._done = true;
};
this._remaining = ms;
this.resume();
}
/** pauses the timer */
pause(): Timer {
if (this._durationTimeoutId && !this._done) {
this._clearTimeoutRef();
this._remaining -= new Date().getTime() - this._start.getTime();
}
return this;
}
/** resumes the timer */
resume(): Timer {
if (!this._durationTimeoutId && !this._done) {
this._start = new Date;
this._durationTimeoutId = setTimeout(this._callback, this._remaining);
}
return this;
}
/**
* clears the timeout and marks it as done.
*
* After called, the timeout will not resume
*/
clearTimeout() {
this._clearTimeoutRef();
this._done = true;
}
private _clearTimeoutRef() {
if (this._durationTimeoutId) {
clearTimeout(this._durationTimeoutId);
this._durationTimeoutId = undefined;
}
}
}
아래와 같이 서버 측 (Node.js)에서 setTimeout을 일시 중지 할 수 있습니다.
const PauseableTimeout = function(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function() {
global.clearTimeout(timerId);
remaining -= Date.now() - start;
};
this.resume = function() {
start = Date.now();
global.clearTimeout(timerId);
timerId = global.setTimeout(callback, remaining);
};
this.resume();
};
아래와 같이 확인할 수 있습니다.
var timer = new PauseableTimeout(function() {
console.log("Done!");
}, 3000);
setTimeout(()=>{
timer.pause();
console.log("setTimeout paused");
},1000);
setTimeout(()=>{
console.log("setTimeout time complete");
},3000)
setTimeout(()=>{
timer.resume();
console.log("setTimeout resume again");
},5000)
나는 당신이 clearTimeout 보다 더 나은 것을 찾을 것이라고 생각하지 않습니다 . 어쨌든 나중에 '다시 시작'하는 대신 언제든지 다른 시간 제한을 예약 할 수 있습니다.
숨길 div가 여러 개인 경우 an setInterval
및 여러 사이클을 사용하여 다음 과 같이 할 수 있습니다 .
<div id="div1">1</div><div id="div2">2</div>
<div id="div3">3</div><div id="div4">4</div>
<script>
function hideDiv(elm){
var interval,
unit = 1000,
cycle = 5,
hide = function(){
interval = setInterval(function(){
if(--cycle === 0){
elm.style.display = 'none';
clearInterval(interval);
}
elm.setAttribute('data-cycle', cycle);
elm.innerHTML += '*';
}, unit);
};
elm.onmouseover = function(){
clearInterval(interval);
};
elm.onmouseout = function(){
hide();
};
hide();
}
function hideDivs(ids){
var id;
while(id = ids.pop()){
hideDiv(document.getElementById(id));
}
}
hideDivs(['div1','div2','div3','div4']);
</script>