2017-08-05 302 views
0

这里是一个简单的倒数计时器,从9到0计数。 倒计时工作正常。但是如果我想暂停它,然后从暂停的位置重新启动,该怎么办? 我试过了(见下面的代码)来中断倒计时,保存它所在的号码,然后从新号码重新启动该功能。但是倒数计时很糟糕,我看不出为什么。有任何想法吗?JS倒数计时器 - 暂停功能

PS。我可以从其他地方剪切和粘贴计时器,但是我正在为了学习体验而做这个。我相信有更好的方法来编写JS中的倒数计时器,但是这让我感到困惑,我无法使这种方式工作,并认为我必须失去明显的东西。

非常感谢

var currentTimeInt = 10; 
 
var minn = []; 
 
var stop = 0; 
 

 
// stop 
 
function stopCounter() { 
 
currentTime = document.getElementById('mins').textContent; // grabs the number of minutes at moment of pause. 
 

 
stop = 1; 
 
    } 
 
    
 
// restart 
 
function restart() { 
 
stop = 0; 
 
currentTimeInt = parseInt(currentTime, 10); // converts that number into an integer we can use 
 
document.getElementById("mins").innerHTML=currentTimeInt; 
 
    newMinutes(); // restarts the newMinutes function with the start time currentTimeInt set to the time the counter stopped at 
 
    } 
 
    
 
function newMinutes() { 
 
document.getElementById('mins').innerHTML= currentTimeInt; // displays the counter 
 

 
for (aa = currentTimeInt-1; aa >= 0; aa--) { 
 
minn.push(aa); // builds an array of numbers in descending order 
 
document.getElementById('mins').innerHTML= minn[aa]; 
 
for (let bb=1; bb<=currentTimeInt; bb++) { 
 
if (bb<currentTimeInt) { 
 
    setTimeout(function timer(){ 
 
\t if (stop == 0) {  // checks if "stop!" has been clicked and returns false to stop the function if that is the case 
 
     document.getElementById('mins').innerHTML= minn[bb]; 
 
\t \t console.log(minn[bb]); 
 
\t } 
 
\t else {return false;} 
 
\t \t }, bb*1000); 
 
\t } 
 

 
} \t 
 
} 
 
console.log(currentTimeInt + " the end"); 
 

 
}
<span>Minutes: </span><span id= "mins"></span> 
 
<button onclick="newMinutes()">Go!</button> 
 
<button onclick="stopCounter()">Stop!</button> 
 
<button onclick="restart()">Reset!</button>

+0

这是一个很好的机会去学习对象和对象方法的基本知识。使用它们可以使任务更简单,并且您可以使用可重用的代码。 – Teemu

+0

按照降序构建数组后,您的想法如何? –

+0

@Teemu好的,我现在要读一读。谢谢你的提示。 –

回答

0

你可以试试这个作为一个例子:

var timerId; 
 
var counter; 
 

 
function start() { 
 
    console.log('start'); 
 
    if (!counter) { 
 
    reset(); 
 
    } else { 
 
    loop(); 
 
    } 
 
} 
 

 
function pause() { 
 
    console.log('pause'); 
 
    if (timerId) { 
 
    clearInterval(timerId); 
 
    timerId = null; 
 
    } 
 
} 
 

 
function reset() { 
 
    console.log('reset'); 
 
    pause(); 
 
    counter = 10; 
 
    loop(); 
 
} 
 

 
function loop() { 
 
    timerId = setInterval(function() { 
 
    if (0 >= counter) { 
 
     pause(); 
 
     return; 
 
    } 
 
    console.log('counter', counter); 
 
    counter--; 
 
    }, 500); 
 
}
<button onclick='start();'>Start</button> 
 
<button onclick='pause();'>Pause</button> 
 
<button onclick='reset();'>Reset</button>

+0

谢谢Arvind ......这很有趣。当我注释掉console.log行时,它不起作用。我不知道console.log内的任何内容实际上是否影响了脚本的功能,我一直认为它只是一个在控制台中记录事情的工具!我仍然有点困惑......无论如何,通过在一个范围内显示counter-counter很容易克服。感谢分享代码....有趣且有帮助! –

+0

@TC,well'console.log'有一个重要的陈述,即'counter - ',我把它移到日志下面,所以现在事情没有日志也能工作。 – Arvind

0

这里的第一个问题是currentTime没有全局定义,因此无法从restart内进行访问。只需在文件的开头放置var currentTime;即可。

但是你必须在你的好不尴尬的方式使用setTimeout另一个严重破的问题。您一次创建多个超时,并根据它们与currentTimeInt的关系给予延迟。这有两个问题。对于一个使用两个for循环不是非常有效,也似乎是多余的,因为你的内部for循环只需要计数到currentTimeInt。其次,你永远不会清除(也可能无法清除)超时。这意味着当你暂停后重启计时器时,如果超时还没有被触发,那么你的程序将运行这些计时器,并让分钟在旧暂停和你在暂停之后创建的新暂停之间跳来跳去。

我知道你的意见,你说你想要得到这个工作,因为你基本上没有自己的整个事情,但它可能不值得继续沿着这条道路。看了一下之后,我认为修复你的程序需要进行重组,否则需要以非常低效的方式来修复程序。如果你是刚刚学习Javascript的人,最好重新开始,并且以正确的方式进行。

下面是使用setInterval而不是setTimeout的更好方法的一个示例,但您可以自行尝试自行解决问题。

(有可以改进下面的代码的功能的方式,但它应该是足以让你的总体思路)

var startTimeInt = 10; 
 
var currentTimeInt = startTimeInt; 
 
var interval = undefined; 
 

 
// start the timer 
 
function startCounter() { 
 
    if(!interval){ 
 
    document.getElementById('mins').innerHTML = currentTimeInt; 
 
    interval = setInterval(newNumber, 1000) // set an interval 
 
    } 
 
} 
 

 
// stop 
 
function stopCounter() { 
 
    // clear the interval 
 
    clearInterval(interval) 
 
    interval = undefined; 
 
} 
 

 
// reset the timer 
 
function resetCounter(){ 
 
    currentTimeInt = startTimeInt; 
 
    document.getElementById('mins').innerHTML = currentTimeInt; 
 
    //stopCounter(); startCounter(); 
 
} 
 

 
// change the time and handle end of time event 
 
function newNumber(){ 
 
    currentTimeInt--; // decrement the current time 
 
    document.getElementById('mins').innerHTML = currentTimeInt; 
 
    if(currentTimeInt == 0){ 
 
    console.log("Done"); 
 
    stopCounter(); 
 
    } 
 
}
<span>Minutes: </span><span id= "mins"></span> 
 
<button onclick="startCounter()">Go!</button> 
 
<button onclick="stopCounter()">Stop!</button> 
 
<button onclick="resetCounter()">Reset!</button>

+0

是的,我开始怀疑是否没有办法清除那些超时。没关系......我对这个来自Free Code Camp的挑战有了一个很好的解决方案,并且我遇到了所有的“用户故事”标准。暂停的事情只是一个奖金。现在我将浏览您编写的代码并使用它直到我理解它。感谢您花时间帮助! –

0

这里是一个工作片段..

var paused = false; 
 
var started = false; 
 
var stopped = true; 
 
var currentCount = 0; 
 
var running = false; 
 
interval = 1000; 
 
maxCount = 10; 
 

 
function start() { 
 
    if (stopped){ 
 
    started = true; 
 
    paused= false; 
 
    stopped = false; 
 
    currentCount = maxCount; 
 
    loop(); running = true; 
 
    return; 
 
    } 
 
    paused= false; 
 
} 
 

 
function pause() { 
 
    paused= true; 
 
} 
 
function stop(){ 
 
paused = false; 
 
started = false; 
 
stopped = true; 
 
running = false; 
 
currentCount = 0; 
 
} 
 

 
function update(item){ 
 
    document.getElementById("status").innerHTML = item; 
 
    //console.log(item); 
 
    --currentCount; 
 
    if(currentCount < 0){stop()} 
 
} 
 

 
function reset() { 
 
    currentCount = maxCount; 
 
    document.getElementById("status").innerHTML = currentCount; 
 
} 
 

 
function loop(){ 
 
    if (!stopped){ 
 
    if (!paused){update(currentCount);} 
 
    setTimeout(function(){loop()}, interval) 
 
    } 
 
}
<button onclick='start();'>Start</button> 
 
<button onclick='pause();'>Pause</button> 
 
<button onclick='reset();'>Reset</button> 
 
<button onclick='stop();'>Stop</button> 
 
<div id="status"></div>

+0

本示例使用递归,即调用其自身的函数。并简单地管理不同的国家并相应地采取行动 – jidexl21

0

这是我的一点用倒计时开始,暂停,恢复,停止& RESET功能:

var jqcd_start_id = 'input#jqcd_start'; 
 
var jqcd_time_id = 'input#jqcd_time'; 
 
var jqcd_count_id = 'span#jqcd_count'; 
 
var jqcd_end_message = 'Time is up!'; 
 

 
var jqcd_countdown = ''; 
 
var jqcd_status = 'stopped'; 
 
var jqcd_current = ''; 
 
function jqcd(action){ 
 
    
 
    if (action == 'start') { 
 
    if (jqcd_status == 'stopped') { 
 
     jqcd_updtv(jqcd_start_id, 'Pause'); 
 
     jqcd_status = 'running'; 
 
     jqcd_current = jqcd_countdown; 
 
     jqcd_updtt(jqcd_count_id, jqcd_countdown); 
 
    } 
 
    else if (jqcd_status == 'running') { 
 
     jqcd_updtv(jqcd_start_id, 'Resume'); 
 
     jqcd_status = 'paused'; 
 
    } 
 
    else if (jqcd_status == 'paused') { 
 
     jqcd_updtv(jqcd_start_id, 'Pause'); 
 
     jqcd_status = 'running'; 
 
    } 
 
    } 
 
    else if (action == 'stop') { 
 
    jqcd_updtv(jqcd_start_id, 'Start'); 
 
    jqcd_status = 'stopped'; 
 
    jqcd_updtt(jqcd_count_id, jqcd_end_message); 
 
    } 
 
    else if (action == 'reset') { 
 
    jqcd_updtv(jqcd_start_id, 'Start'); 
 
    jqcd_status = 'stopped'; 
 
    jqcd_updtt(jqcd_count_id, jqcd_countdown); 
 
    } 
 
    
 
    var a = jqcd_current.split(":"); 
 
    var m = a[0]; 
 
    var s = (a[1] - 1); 
 
    
 
    if (s < 0) { 
 
    if (parseInt(m) == 0) { 
 
     jqcd_updtv(jqcd_start_id, 'Start'); 
 
     jqcd_status = 'stopped'; 
 
     jqcd_updtt(jqcd_count_id, jqcd_end_message); 
 
    } 
 
    else { 
 
     m = m - 1; 
 
     s = 59; 
 
    } 
 
    } 
 
    
 
    if(s >= 0){ 
 
    setTimeout(function(){ 
 
     if (jqcd_status == 'running') { 
 
     m = (parseInt(m) < 10)? "0" + parseInt(m): m; 
 
     s = (parseInt(s) < 10)? "0" + parseInt(s): s; 
 
     jqcd_updtt(jqcd_count_id, m + ":" + s); 
 
     jqcd_current = m + ":" + s; 
 
     jqcd(''); 
 
     } 
 
    }, 1000); 
 
    } 
 
} 
 

 
function jqcd_updtv(selector, value) { 
 
    if (selector != '') { 
 
    $(selector).val(value); 
 
    } 
 
} 
 
function jqcd_updtt(selector, value) { 
 
    if (selector != '') { 
 
    $(selector).text(value); 
 
    } 
 
} 
 

 
$(document).ready(function() { 
 
    jqcd_countdown = $(jqcd_time_id).val(); 
 
    jqcd_updtt(jqcd_count_id, jqcd_countdown); 
 
    
 
    $(jqcd_time_id).keyup(function() { 
 
    jqcd_countdown = $(jqcd_time_id).val(); 
 
    jqcd_updtt(jqcd_count_id, jqcd_countdown); 
 
    jqcd_updtv(jqcd_start_id, 'Start'); 
 
    jqcd_status = 'stopped'; 
 
    }); 
 
});
span#jqcd_count { 
 
    font-size: 20pt; 
 
    font-weight: bold; 
 
} 
 
input#jqcd_start, 
 
input#jqcd_stop, 
 
input#jqcd_reset { 
 
    font-size: 12pt; 
 
    font-weight: bold; 
 
} 
 
input#jqcd_start, 
 
input#jqcd_stop, 
 
input#jqcd_reset { 
 
    width: 100px; 
 
} 
 
span#jqcd_count { 
 
    font-family: "Lucida Console", Monaco, "Courier New", Courier, monospace !IMPORTANT; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<span id="jqcd_count">00:30</span><br><br> 
 
<input type="button" id="jqcd_start" value="Start" onClick="jqcd('start')" /> 
 
<input type="button" id="jqcd_stop" value="Stop" onClick="jqcd('stop')" /> 
 
<input type="button" id="jqcd_reset" value="Reset" onClick="jqcd('reset')" /><br><br> 
 
<input type="text" id="jqcd_time" value="00:10" /> 
 
<br><br>

这是很简单的定制。 JavaScript代码中的前四个变量可以适用于您的特定HTML。

如果您想要每秒执行一次操作,请在“jqcd_updtt”函数中添加您的代码行。

当然,CSS是完全可选的。

通过更改“jqcd_time”字段中的值动态设置倒计时开始时间。但是,如果要为倒数起点设置静态值,则可以在JavaScript代码末尾更改“$(document).ready(function(){”函数中的变量。

PS。 这个倒计时已经为几分钟或几秒钟

0

关于保持它所KISS没有上限!

let i = 9,j 
 
function chrono(){ 
 
    if (i>=0){ 
 
    now.innerText = i-- 
 
    } 
 
}
<h1><div id="now">⏰ Ready!</div> 
 
<button onclick="setInterval(function(){ chrono() }, 1000);this.style.display='none'">Start</button> 
 
<button onclick="i=10">Reset</button> 
 
<button onclick="j=i;i=-1">Pause</button> 
 
<button onclick="i=j">Continue</button>

这是准备到b的最基本的例子e扩大,大多没有clearInterval

KISS原则指出,如果保持 简单而不是复杂,大多数系统工作得最好;因此简化应该是设计中的关键目标,应避免不必要的复杂性。 https://en.wikipedia.org/wiki/KISS_principle

因此,JS增量和setInterval似乎很容易,但他们隐藏复杂的事情。

另一种方法是使用date.now(),它提供基于系统时钟的准确unix时间戳和用于发出嘟嘟声的web音频api。

i = Date.now();j=i+10000;z.innerText="Target @"+j 
 
function d(){ 
 
    if(now.innerText < j){ 
 
     now.innerText = Date.now() 
 
     k(3,603,80) 
 
     } 
 
    if(now.innerText > j){ 
 
     now.innerHTML = "<b>TARGETED!</b>" 
 
     k(8,728,100) 
 
     }   
 
    } 
 

 
setInterval(function(){ d() }, 100) 
 

 
a=new AudioContext() 
 
function k(w,x,y){ 
 
    v=a.createOscillator() 
 
    u=a.createGain() 
 
    v.connect(u) 
 
    v.frequency.value=x 
 
    v.type="square" 
 
    u.connect(a.destination) 
 
    u.gain.value=w*0.01 
 
    v.start(a.currentTime) 
 
    v.stop(a.currentTime+y*0.001) 
 
}
EPOCH: <out id="now"></out><h6 id="z">