2011-10-05 107 views
2

我是Javascript的初學者。我正在試着做一個計時器。它的工作原理很好,但是當涉及到PauseStop按鈕,他們根本就不運行良好......使用JavaScript製作簡單的計時器,但得到奇怪的行爲

  • 對於Pause按鈕..讓說,計時器上0:58當按下按鈕Pause,它在0:58停止,但是當我再次按它恢復 倒計時..它只是成爲0:57 ..並且之後停止,它 不會繼續到0:00!

  • 而對於Stop按鈕。當我只需按下它,它給這個錯誤 :

    未捕獲的ReferenceError:checkstate沒有定義

這裏的結合整個代碼,以便你們可以測試它,讓我知道如果還有其他東西:

<!DOCTYPE html> 
<html> 
    <head> 
     <style> 
      html, body, p, input, button { 
       margin:0; 
       padding:0; 
      } 

      html , body { 
       height : 100%; 
      } 

      #mainContent { 
       width : 300px; 
       height : 200px; 
       margin: 50px auto; 
      } 

      #seconds { 
       padding : 10px; 
       font-size : 15px; 
       font-weight:bold; 
      } 

      button { 
       padding : 10px; 
      } 

      #interfereButton { 
       margin : 0 40px; 
      } 


      #timer {   
       width : 200px; 
       height: 100px; 
       margin-top: 20px; 
       font-weight:bold; 
       font-size : 60px; 
       text-align : center; 
      }   
     </style> 
     <title>Timer</title>   
    </head> 

    <body> 
      <div id="mainContent"> 
       <div id="userControl"> 
        <input type="text" name="seconds" id="seconds"/> 
        <button id="start">Start</button> 
       </div> 
       <p id="timer">0:00</p> 
       <div id="interfereButton"> 
        <button id="pause">Pause</button> 
        <button id="stop">Stop</button> 
       </div> 
       <script> 
        var timer = document.getElementById("timer"); 
        var start = document.getElementById("start"); 
        var startPoint = document.getElementById("seconds"); 
        var userControl = document.getElementById("userControl"); 
        var userInterfere = document.getElementById("interfereButton"); 
        var pause = document.getElementById("pause"); 
        var stop = document.getElementById("stop"); 

        var timerHandle; 
        var tempValue; 

        function checkState(){ 
         if (timer.innerHTML == "0:00"){ 
          userControl.style.display = "block"; 
          userInterfere.style.display = "none"; 
          timer.style.color = "black"; 
         } else { 
          userControl.style.display = "none"; 
          userInterfere.style.display = "block"; 
         } 
        } 

        function activate(x){ 
         var min = x.split(":")[0]; 
         var sec = x.split(":")[1]; 

         if(min >= 0){ 
          sec--; 
          if(sec < 0){ 
           sec = 59; 
           min--; 
           if(min < 0) { 
            sec = "00" ; 
            min = 0 ;    
            clearInterval(timerHandle); 
           }   
          } else if(sec < 10) { 
           sec = "0" + sec; 
           timer.style.color = "red";   
          } 
          timer.innerHTML = min + ":" + sec ; 
         } else { 
          clearInterval(timerHandle); 
         } 

         checkState(); 
        } 


        start.onclick = function() { 
         if(!isNaN(startPoint.value)){ 
          timer.innerHTML= startPoint.value + ":00" ; 
          userControl.style.display = "none"; 
          userInterfere.style.display = "block"; 
          timerHandle = setInterval("activate(timer.innerHTML)" , 1000); 
         } else { 
          alert("Sorry, only numerical values are allowed."); 
         } 
        } 

        pause.onclick = function() { 
         if(pause.innerHTML == "Pause"){ 
          tempValue = timer.innerHTML; 
          clearInterval(timerHandle); 
          pause.innerHTML = "Resume"; 
         } else if(pause.innerHTML == "Resume"){ 
          timerHandle = setInterval("activate(tempValue)" , 1000); 
          pause.innerHTML = "Pause"; 
         } 
        } 

        stop.onclick = function(){ 
         clearInterval(timerHandle); 
         timer.innerHTML = "0:00"; 
         checkstate(); 
        } 

        window.onload = function(){ 
         userInterfere.style.display = "none"; 
        } 
       </script> 
      </div> 
    </body> 

</html> 
+2

糾正我,如果我錯了,但他應該包裹JS中的函數防止全局變量? –

+1

@ZachL .:你是對的。明確聲明一個變量爲全局變量比允許所有外部變量變量默認爲全局變量更好。 – benekastah

+0

@ZachL。你能告訴我該怎麼做嗎?它只是用'function(){...}'包裝代碼? –

回答

4

您的問題是當您嘗試恢復時,您正在呼叫設置的時間間隔通過tempValue。然後tempValue不會被改變。所以每當你的間隔發生時,它都會傳遞相同的值。你可以通過刪除tempValue和使用timer.innerHTML來解決這個問題,就像你最初一樣。

http://jsfiddle.net/WkuSG/

至於停止按鈕,檢查方法名,你typoed,在S應該是國會大廈。


其他一些說明。你真的不應該使用setInterval傳遞一個字符串。內部使用eval這是不好的。傳遞一個函數更好。這樣的事情:

setInterval(function(){ 
    activate(timer.innerHTML); 
}, 1000); 

最後,你不能指望setInterval是準確的。如果此計時器需要非常準確,則需要比較時間戳。由於JavaScript是單線程的,其他一些JavaScript可能最終會拋棄你的時間。

+2

我剛剛更新我的答案,包括此:P – geekchic

+0

噢,謝謝你解決它。謝謝你的提示。但我是一個初學者,你可以澄清關於'setInterval'的說明不準確嗎? –

+3

Re:關於'setInterval'的準確性,請參閱John Resig所說的內容:http://ejohn.org/blog/how-javascript-timers-work/ – Cheeso

1

我可以回答你的問題的一部分:我在您調用checkstate()時,您的stop.onclick函數稱爲checkState。 JavaScript區分大小寫。

1

首先,

您致電checkstate()是錯誤的。它與定義的函數checkState不同。

B.我不知道你在做暫停/結果tempValue。也不需要將值傳遞給你的滴答功能(你稱之爲「激活」,但它確實是一個勾號)。在tick函數中,只需獲取DIV的內容。

工作示例: http://jsbin.com/ohoqot

還,這是一個好主意,包裹在一個範圍內的功能:

(function(globalScope) { 
    'use strict'; 

    var timer, start, startPoint, userControl, userInterfere, pause, 
     stop, timerHandle, tempValue; 

    function tick() { .... } 

    ... other functions here ... 

    window.onload = function(){ 
     setGlobals(); 
     setupBindings(); 
     userInterfere.style.display = "none"; 
    }; 

}(this)); 
+0

感謝您的努力。它確實有幫助。 –