2012-08-05 52 views
0

我正在使用下面的腳本,我正在嘗試做的是設置一個自定義時間到腳本,併爲它自動更新,而無需每次重新設置時間。 (我只想當設定的時間,並希望我的腳本來跟蹤時間和顯示它)基於自定義時間的Javascript時鐘

當我運行該腳本,它顯示:楠:楠:NaN的AM

我的代碼如下:

<div id="js_clock"> display clock here </div> 

<script language="javascript"> 
    function js_clock(clock_time) 
    { 
     var clock_hours = clock_time.getHours(); 
     var clock_minutes = clock_time.getMinutes(); 
     var clock_seconds = clock_time.getSeconds(); 
     var clock_suffix = "AM";  
     if (clock_hours > 11){ 
     clock_suffix = "PM"; 
     clock_hours = clock_hours - 12; 
     } 
     if (clock_hours == 0){ 
     clock_hours = 12; 
     } 

     if (clock_hours < 10){ 
     clock_hours = "0" + clock_hours; 
     } 

     if (clock_minutes < 10){ 
     clock_minutes = "0" + clock_minutes; 
     } 

     if (clock_seconds < 10){ 
     clock_seconds = "0" + clock_seconds; 
     } 

     var clock_div = document.getElementById('js_clock'); 
     clock_div.innerHTML = clock_hours + ":" + clock_minutes + ":" + clock_seconds + " " + clock_suffix; 
     setTimeout("js_clock()", 1000); 
    } 

    var serverTime = new Date("09:20:50"); 
    js_clock(serverTime); 
</script> 

回答

0

你的代碼中有一些嚴重的缺陷,如以下。

setTimeout不會按照設定的間隔運行,但只要後面可以運行,這個時鐘就會慢慢漂移,有時會很多。

將字符串傳遞給Date並期待它被正確解析是有問題的。在ECMA-262 ed 3中,它完全依賴於實現,在ES5中,該字符串需要是ISO8601長格式的自定義版本(但請注意,並非所有使用的瀏覽器都支持ES5)。

最後,如果客戶端忙,該功能可能不會運行幾秒鐘,因此時鐘需要基於客戶端時鐘,然後根據時間差異進行調整。

以下函數完成以上所有操作。

<script type="text/javascript"> 
var customClock = (function() { 

    var timeDiff; 
    var timeout; 

    function addZ(n) { 
    return (n < 10? '0' : '') + n; 
    } 

    function formatTime(d) { 
    return addZ(d.getHours()) + ':' + 
      addZ(d.getMinutes()) + ':' + 
      addZ(d.getSeconds()); 
    } 

    return function (s) { 

    var now = new Date(); 
    var then; 

    // Set lag to just after next full second 
    var lag = 1015 - now.getMilliseconds(); 

    // Get the time difference if first run 
    if (s) { 
     s = s.split(':'); 
     then = new Date(now); 
     then.setHours(+s[0], +s[1], +s[2], 0); 
     timeDiff = now - then; 
    } 

    now = new Date(now - timeDiff); 

    document.getElementById('clock').innerHTML = formatTime(now); 
    timeout = setTimeout(customClock, lag); 
    } 
}()); 


window.onload = function() { 
    customClock('09:20:50'); 
} 

</script> 

<div id="clock"></div> 
2

我想你已經忘記了將參數傳遞給js_clock()。也許你務必做好:

setTimeout(
    function() { 
     //Call the function again updating seconds by 1 
     js_clock(
      new Date(
       clock_time.getFullYear(), 
       clock_time.getMonth(), 
       clock_time.getDate(), 
       clock_time.getHours(), 
       clock_time.getMinutes(), 
       clock_time.getSeconds() + 1 
      ) 
     ); 
    }, 
    1000 
); 

編輯: 我錯過了這個可以用一個函數調用來做到這一點:

setTimeout(
    function() { 
     js_clock(new Date(+clock_time + 1000)); 
    }, 
    1000 
); 

+clock_time聲明Date對象轉換爲從UNIX毫秒Epoch,所以更新時間就像加上1000毫秒一樣簡單。 由於用戶RobG ;-)

+1

你[不要傳字符串'的setTimeout()'](http://stackoverflow.com/questions/6081560/is-there-ever-a-good-reason-to-pass-a -string到的setTimeout);它是[邪惡,像'eval()'](http://stackoverflow.com/a/6232610/82548)。 – 2012-08-05 23:35:38

+1

好悲傷,「eval是邪惡的」事物需要休息。當然這不是最佳的,但它不是邪惡的。更好地評論爲什麼這6個函數調用是爲了取代none:'new Date(+ clock_time + 1000)' – RobG 2012-08-06 01:43:25

+0

@RobG:我的鏈接文本用來解釋我所鏈接的答案,而不是深深地相信'eval()===邪惡'的概念。我鏈接到其他頁面的唯一原因是支持我的請求,而不是將字符串傳遞給'setTimeout'。不過,也許我應該更好地選擇我的話。 – 2012-08-07 14:59:54

2

你必須創建之日起,new Date("09:20:50");返回無效的日期問題。如果你想設置小時分秒使用

new Date(year, month, day [, hour, minute, second, millisecond ]) 

或者看看here

你也忘了傳遞日期的setTimeout的,請嘗試:

setTimeout(function() { 
    js_clock(new Date(/*pass hours minutes and seconds here*/)) 
}, 1000); 
0

WAIT!剛剛意識到,這仍然沒有顯示正確的時間。錯誤消失了,但時間不是你正在尋找的。

window.js_clock = function js_clock(clock_time) { 
    var clock_hours = clock_time.getHours(); 
    var clock_minutes = clock_time.getMinutes(); 
    var clock_seconds = clock_time.getSeconds(); 
    var clock_suffix = "AM"; 
    if (clock_hours > 11) { 
     clock_suffix = "PM"; 
     clock_hours = clock_hours - 12; 
    } 
    if (clock_hours === 0) { 
     clock_hours = 12; 
    } 

    if (clock_hours < 10) { 
     clock_hours = "0" + clock_hours; 
    } 

    if (clock_minutes < 10) { 
     clock_minutes = "0" + clock_minutes; 
    } 

    if (clock_seconds < 10) { 
     clock_seconds = "0" + clock_seconds; 
    } 

    var clock_div = document.getElementById('js_clock'); 
    clock_div.innerHTML = clock_hours + ":" + clock_minutes + ":" + clock_seconds + " " + clock_suffix; 
    setTimeout("js_clock(new Date())", 1000); 
} 

var serverTime = new Date("09:20:50"); 
window.js_clock(serverTime);​ 
+0

不要對字符串使用'setTimout'。請參閱http://stackoverflow.com/questions/6081560/is-there-ever-a-good-reason-to-pass-a-string-to-settimeout。 – Zeta 2012-08-05 23:40:22

+0

@Zeta我對OP的代碼做了最小的修改。 :) – bPratik 2012-08-05 23:46:27

+0

@bPratik - 這似乎從我的電腦獲得時間。我希望能夠手動設置時間,並根據我設置的時間每秒更新一次。 – Aaron 2012-08-05 23:51:55