2017-08-05 124 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">