提醒一下,你不应该依赖这个来获得高安全性,有人可以很容易地阅读源代码并找出链接。即使你混淆了它,如果浏览器可以解码它,那么一个坚定的人也可以。
var twentyMins = 20 * 60; // 20 minutes * 60 seconds
window.onload = function() {
countDown('my_div1', '<a href="cdtl.html">Hello 1</a>', twentyMins);
}
function countDown(elID, output, seconds) {
var mins,
secs = seconds,
pad = function (n) {
return n > 9 ? n : '0' + n;
};
// get the hours by dividing by the number of seconds in an hour
hours = Math.floor(secs / 3600); // 60 * 60 = 3600
// get the remaining seconds
secs %= 3600;
// likewise, get the number of minutes of by dividing the remaining seconds by 60
mins = Math.floor(secs / 60);
// again, get the remainder of seconds
secs %= 60;
// pad any numbers less than 9 with a leading 0
secs = pad(secs);
mins = pad(mins);
hours = pad(hours);
document.getElementById(elID).innerHTML = (seconds === 0) ? output : 'Time until link appears: ' + hours + ':' + mins + ':' + secs;
// instead of returning, just don't call setTimout if we are done
if (seconds !== 0) {
seconds -= 1;
// there is no need to pass a string to setTimout, you just pass the function name,
// followed by the timeout in ms, followed by any params
setTimeout(countDown, 1000, elID, output, seconds);
}
}
jsFiddle
但是setInterval
,使用而不是重写它会是一个更好的主意setTimeout
。这是因为定时器不可靠且定时器延迟长度无法保证。DoingsetTimeout(something, 1000)
可能会在something
一秒钟后执行,或者它可能something
会在那之后的某个时间执行。它可能只会在这里和那里只有几毫秒,但在任何相当长的时间内它都会加起来。
即使是像盒子这样简单的东西也会alert
停止你setTimeout
的倒计时!下面的代码通过重新计算每次运行时剩余的秒数每半秒更新一次计数器。我们仍然可以使用 来做到这一点setTimeout
,但setInterval
更适合这项工作。如果浏览器由于某种原因陷入困境,setInterval
只会放弃一些执行,而不是试图追赶。这很好,因为它每次运行时都会重新计算剩余时间。这也意味着如果alert
弹出一个,也没关系。
另一个不依赖setTimeout
s 序列在每次运行时递减计数器的好理由是,在我们现代的选项卡式浏览器世界中,后台选项卡的计时器分辨率通常会降低,这也可能是由于笔记本电脑的电源管理而发生的。通常这意味着从 4ms 到 15ms 的最小分辨率,所以在这种情况下它不应该打扰我们,但是在使用计时器时你需要知道这一点。
var twentyMins = 20 * 60; // 20 minutes * 60 seconds
window.onload = function() {
countDown('my_div1', '<a href="cdtl.html">Hello 1</a>', twentyMins);
}
function countDown(elID, output, seconds) {
"use strict";
var timer, // timer will hold a reference to the id of our interval
// store a reference to the element so we don't have to keep looking it up
el = document.getElementById(elID),
getTime = function () {
// get the current time in ms since Unix epoch
return (new Date()).getTime();
},
// we will be done counting down when we are
// `seconds` seconds from the current time
finishAt = getTime() + (seconds * 1000),
pad = function (n) {
return n > 9 ? n : '0' + n;
},
lastCount = -1,
update = function () {
var hours,
now = getTime(),
mins,
// the seconds remaining is the finish time
// minus the current time divided by 1000ms
secs = Math.floor((finishAt - now) / 1000);
// Since we might be running this update function more than once
// a second, check to see if the number of seconds has changed since
// our last run. If it hasn't there is no need to do any more calculations
// nor update the DOM.
if (lastCount !== secs) {
lastCount = secs;
// you need to make sure the current time is equal to OR GREATER THEN the finish time
// because the interval could have actually fired sometime (shortly)
// after the time stored in finishAt
if (now >= finishAt) {
clearInterval(timer);
el.innerHTML = output;
} else {
// get the hours by dividing by the number of seconds in an hour
hours = Math.floor(secs / 3600); // 60 * 60 = 3600
// get the remaining seconds
secs %= 3600;
// likewise, get the number of minutes of by dividing the remaining seconds by 60
mins = Math.floor(secs / 60);
// again, get the remainder of seconds
secs %= 60;
secs = Math.floor(secs);
// pad any numbers less than 9 with a leading 0
secs = pad(secs);
mins = pad(mins);
hours = pad(hours);
el.innerHTML = 'Time until link appears: ' + hours + ':' + mins + ':' + secs;
}
}
};
// display the counter right away
update();
// start the timer, updating twice a second to try and avoid
// having the counter seem to skip numbers
timer = setInterval(update, 499);
}
jsFiddle
您可能已经注意到,在我提出的两种解决方案中,我在计算不同的时间分量时都使用了余数运算符。我这样做是因为使用余数运算符比乘以将分钟作为秒然后减去要快。您可能还注意到我的代码使用了严格的等式/不等式比较运算符 ===
and!==
而不是==
and !=
。这种编码风格不仅会减少JSLint 对您的感情造成的伤害,而且速度也会稍微快一些。
在第二个更好的解决方案中,变量lastCount
存储了上一次执行后剩余的总秒数。由于代码将每秒运行一次以上,因此查看自上次以来结果是否已更改很有用。如果没有,我们就不必再做任何工作了。我们不必计算分钟,更重要的是我们不必接触 DOM,因为DOM 访问速度很慢。