Javascript WebKit设置间隔和系统时间更改

Javascript WebKit设置间隔和系统时间更改,javascript,webkit,Javascript,Webkit,我在创建简单任务时遇到了以下问题:使用WebKit引擎显示html时钟。额外的要求是处理系统时间变化,并且它应该在Windows上工作。 我已经使用setInterval实现了这一点,但在我向后更改系统时间后,它似乎冻结了浏览器。 对我来说,这看起来像是WebKit的问题。通过运行以下简单代码,在safari上很容易复制: <p id="date"></p> setInterval(SetTime, 1000); function SetTime() { document

我在创建简单任务时遇到了以下问题:使用WebKit引擎显示html时钟。额外的要求是处理系统时间变化,并且它应该在Windows上工作。 我已经使用setInterval实现了这一点,但在我向后更改系统时间后,它似乎冻结了浏览器。 对我来说,这看起来像是WebKit的问题。通过运行以下简单代码,在safari上很容易复制:

<p id="date"></p>
setInterval(SetTime, 1000);
function SetTime() {
document.getElementById('date').textContent=new Date();
}

你知道为什么会发生这种情况以及如何解决吗?

这几乎肯定是WebKit的问题

问题 当您使用
setTimeout
时,您将创建一个具有两个属性的“计时器”:

  • 时间戳,设置为现在+指定的延迟
  • 当系统时间大于时间戳时,将触发一次回调
您可以想象
setTimeout
的一个幼稚的实现如下所示:

var timers = [];
function setTimeout(callback, delay) {
    var id = timers.length;
    timers[id] = {
        callback: callback,
        timestamp: Date.now() + delay
    }
    return id;
}
这只需创建一个计时器并将其添加到列表中。然后,JS运行时将在每次勾选时检查这些计时器,并对已触发的计时器执行回调:

var now = Date.now();
for(var id in timers) {
    var timer = timers[id];
    if(timer && timer.timestamp < now) {
        callback();
        delete timers[id];
    }
}
结论 这对您来说可能不是什么好消息,但您可能应该重写整个应用程序以使用
requestAnimationFrame
——它似乎更适合您的需要:

var onNextFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
var dateElem = document.getElementById('date');

var updateDate = function(timestamp) {
    dateElem.textContent = new Date();
    onNextFrame(updateDate);
};
onNextFrame(updateDate);

谢谢你,吉姆。我会试试你的解决办法。我已经向WebKit团队报告了这个问题。很高兴为您服务。请让我知道这是否有效(如果有效,请接受答案)!
var lastTimestamp;
var onNextFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;

var checkForPast = function(timestamp) {
    if(lastTimestamp && timestamp < lastTimestamp) {
        console.error('System time moved into the past! I should probably handle this');
    }
    lastTimestamp = timestamp;
    onNextFrame(checkForPast);
};

onNextFrame(checkForPast);
var onNextFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
var dateElem = document.getElementById('date');

var updateDate = function(timestamp) {
    dateElem.textContent = new Date();
    onNextFrame(updateDate);
};
onNextFrame(updateDate);