1

我写了以下函数:

function fill(value) {
    return (value > 9) ? "" + value : "0" + value;
}

function fillMili(value) {
    value %= 1000;
    return (value <= 9) ? "00" + value : 
           (value <= 99) ? "0" + value :
           "" + value;  
};

function showClock() {
    var now = new Date;

    time = fill(now.getHours()) + " : " + fill(now.getMinutes()) + " : " + fill(now.getSeconds()) + " : " + fill(now.getMilliseconds());

    document.getElementById("clock").innerHTML = time;

    setTimeout("showClock()",1);
}

然后将函数放入body标签并创建一个div标签:

<body onload="showClock()">
    <div id="clock">
    </div>

该页面将显示一个精美的时钟。但是如果我改变这行代码

setTimeout("showClock()",1);

setInterval("showClock()",1);

浏览器将在加载此页面时冻结。

我知道该函数setTimeout()将执行一次分配的函数,该函数setInterval()将多次执行分配的函数。

我有 2 个问题:工作的onload属性如何body以及为什么该函数setInterval()在此代码中不起作用?

更新:我想显示一个显示毫秒的时钟。该属性是否onload重复该功能?

4

4 回答 4

2

这是 setInterval 的语法:

var intervalID = window.setInterval(func, delay[, param1, param2, ...]);

以毫秒为单位的延迟。除此之外,这种延迟还有一个古老的限制:

最小/最大延迟和超时嵌套

从历史上看,浏览器实现 setTimeout() “钳制”:延迟小于“最小延迟”限制的连续 setTimeout() 调用被强制使用至少最小延迟。最小延迟 DOM_MIN_TIMEOUT_VALUE 为 4 毫秒(存储在 Firefox 的首选项中:dom.min_timeout_value),DOM_CLAMP_TIMEOUT_NESTING_LEVEL 为 5 毫秒。

事实上,4ms 是由 HTML5 规范指定的,并且在 2010 年及以后发布的浏览器中是一致的。在 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) 之前,嵌套超时的最小超时值为 10 毫秒。

来源:Mozilla

除了上述最小延迟的事实之外,您还应该问自己一个问题,为什么要每毫秒运行一次时钟功能。您最好每 1000 毫秒 = 1 秒执行一次。

如果你想显示毫秒,你应该找到另一种显示方式,因为最小延迟仍然有效。

于 2013-09-15T08:29:06.830 回答
1

setInterval(....) 函数中的时间参数以毫秒为单位。1 毫秒对于执行函数来说非常快,这可能就是页面冻结的原因。尝试将其设置为 1000(1000 毫秒 = 1 秒)。

请参阅此处了解更多信息:http ://www.w3schools.com/jsref/met_win_setinterval.asp

于 2013-09-15T08:26:14.917 回答
1

浏览器不应冻结。去掉标签onload中的并将其放在页面部分中:<body><head>

window.onload = function() {
    var clock = document.getElementById("clock");
    window.setInterval(showClock, 1);
    showClock();
    function showClock() {
        var now = new Date();
        var time = fill(now.getHours()) + " : " + fill(now.getMinutes()) + " : " + fill(now.getSeconds()) + " : " + fill(now.getMilliseconds());
        clock.innerHTML = time;
    }
}

这应该使它更快,更优雅。

现场测试用例

于 2013-09-15T08:43:00.380 回答
0

考虑到当前的浏览器实现和硬件,也许您应该意识到您正在尝试做的事情是不可能的。

在我的电脑上,Chrome 在屏幕上重新绘制 3x16 区域所需的时间约为 300 毫秒。有 1000 个这样的更新需要 5 分钟。你想做一秒钟。你显然对你的硬件要求太多了。

如果您真的需要在网络浏览器中获得如此高的性能(好像......),您应该编写一个本机插件,但我仍然怀疑您是否能够每秒多次重绘屏幕的一部分(至少您需要一个 1000hz 的显示器,生产起来会很愚蠢)。

重新考虑您的应用程序逻辑:即使您显示毫秒时钟,人眼也看不到任何变化快于每秒 72 次的东西,因此您也可以将时钟更新为更合理的〜每秒 25 次,没有人就能看出区别。它仍然是我不想使用的网站,因为它会降低我的浏览器速度,但至少它不会冻结。

使用没有 2 和 5 因子的数字将确保显示的最后一个数字不会重复太频繁

setInterval("showClock()", 37);

编辑:

正如 Shadow Wizard 所指出的,您的代码中存在一个更大的问题,即您每次更新时钟时都会调用 setInterval ,这会尽可能快地设置很多计时器。您应该只调用一次该函数,例如在 onload 事件中:

<body onload="startClock()">

然后添加startClock函数:

function startClock() { setInterval("showClock()", 1); }

并从以下位置删除setInterval呼叫showClock

function showClock() {
    var now = new Date;

    time = fill(now.getHours()) + " : " + fill(now.getMinutes()) + " : " + fill(now.getSeconds()) + " : " + fill(now.getMilliseconds());

    document.getElementById("clock").innerHTML = time;

    // remove! //setTimeout("showClock()",1);
}

我仍然建议您不需要经常更新您的页面,但这是您的决定。

于 2013-09-15T08:54:24.953 回答