我正在尝试构建一个时钟,它将在没有即时服务器请求的情况下显示服务器时间。目的是 - 我需要一个时钟,它可以同时显示每个用户并且不会发出太多服务器请求)。
我想将实际服务器时间传递给 JavaScript,而不仅仅是计算秒数,但几分钟后我意识到随机浏览器上存在巨大差异。怎么解决呢?造成这种差异的原因是什么?如果我检查函数的执行时间,它总是显示 1-4 毫秒,但看起来,在一个浏览器上时钟每秒丢失超过 60 毫秒,而在另一个浏览器中仅丢失 10 毫秒。
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
function startTime(sTime) {
sTime = typeof sTime !== 'undefined' ? sTime : 0;
nowDateInput = $('#todaydate').html(); // 2014, 07, 02, 08, 14, 35
nn = nowDateInput.split(',');
if (nn[1] == 0) {
nn[1] = 12;
} else {
nn[1] = nn[1] - 1;
}
today = new Date(nn[0], nn[1], nn[2], nn[3], nn[4], nn[5]);
today.setSeconds(today.getSeconds()+sTime);
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('clock').innerHTML = h+":"+m+":"+s;
var t = setTimeout(function(){startTime(sTime)},1000);
sTime = sTime + 1;
}
function checkTime(i) {
if (i<10) {i = "0" + i};
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="todaydate" style="display:none;">2014, 07, 02, 08, 14, 35</div><!-- This field is normally passed from Django-View to Template -->
<div id="clock"></div>
</body>
</html>
我正在考虑同时运行 JavaScript 时钟并测量 now() 和页面打开状态之间的差异。这会是一个好的解决方案吗?
================================================== =========
编辑:
取ServerTime和当前JS-Time之间的差异是一个很好的解决方案。这是我当前的解决方案,其精度始终为 lt 1s。
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
function startTime(initJSTime) {
// page-load JS-time
if (typeof initJSTime === 'undefined') {
initJSTime = new Date();
}
// Current JS-Time
var todayJS = new Date();
// Converting Server-Time when page is loaded to JS-Date
nowDateInput = $('.todaydate').html();
nn = nowDateInput.split(',');
if (nn[1] == 0) {
nn[1] = 12;
} else {
nn[1] = nn[1] - 1;
}
var today = new Date(nn[0], nn[1], nn[2], nn[3], nn[4], nn[5]);
// Difference between Current JS-time and page-load JS-time
var initDiffmSec = todayJS - initJSTime;
// Setting Clock-Time as sum of Server-Time and Difference
today.setMilliseconds(today.getMilliseconds()+initDiffmSec);
// Output-presentation of the clock
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('clock').innerHTML = h+":"+m+":"+s;
// next function call
var t = setTimeout(function(){startTime(initJSTime)},1000);
}
function checkTime(i) {
if (i<10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="todaydate" style="display:none;">2014, 07, 02, 08, 14, 35</div><!-- This field is normally passed from Django-View to Template -->
<div id="clock"></div>
</body>
</html>
最佳答案
您可以创建基于服务器发送的时间值的页内版本。希望评论足够。
<script>
// Unix time value from server: seconds since 1970-01-01T00:00:00Z
// Below is a number for 2014-07-02T06:48:24.000Z, set to actual server value
var serverTime = 1404283704;
var doClock = (function () {
// Calc offset from server time
// Javascript time value is milliseconds since above epoch
var serverOffset = serverTime - (new Date() / 1000 | 0);
// Helper
function z(n){return (n<10?'0':'') + n}
return function() {
// Create a new Date object each time so
// it doesn't matter if a second or more is skipped
var now = new Date();
// Adjust for server offset
now.setSeconds(now.getSeconds() + serverOffset);
// write clock to document, values are local, not UTC
document.getElementById('clock').innerHTML = now.getFullYear() + '-' +
z(now.getMonth()+1) + '-' +
z(now.getDate()) + ' ' +
z(now.getHours()) + ':' +
z(now.getMinutes()) + ':' +
z(now.getSeconds());
// Run again just after next full second
setTimeout(doClock, 1020 - now.getMilliseconds());
};
}());
window.onload = doClock;
</script>
<div id="clock"></div>
一旦加载脚本,就会出现服务器延迟,因此请将其放置在尽可能靠近页面顶部的位置,以最大程度地减少延迟。
关于javascript - 使用 Django + JavaScript 的服务器时钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24524318/