我正在尝试制作倒数计时器,其中包含20分钟后出现的链接。这就是我到目前为止......
<script type="text/javascript">
window.onload = function()
{
countDown('my_div1', '<a href="cdtl.html">Hello 1</a>', 720);
}
function countDown(elID, output, seconds)
{
document.getElementById(elID).innerHTML = (seconds==0) ? output : 'Time until link appears: ' + seconds;
if(seconds==0) { return; }
setTimeout("countDown('"+elID+"', '"+output+"', "+(seconds-1)+")", 1000);
}
</script>
它有效,但这就是我想要做的。如何将20分钟的间隔更改为20:00:00而不是720秒呢?
答案 0 :(得分:1)
Shehabix回答了你的问题,但我想建议重写你的代码:
window.onload = function() {
countDown('my_div1', '<a href="cdtl.html">Hello 1</a>', 720);
}
function countDown(elID, output, seconds) {
var elem = document.getElementById(elID),
start = new Date().getTime(), end = start+seconds*1000,
timer = setInterval(function() {
var now = new Date().getTime(), timeleft = end-now, timeparts;
if( timeleft < 0) {
elem.innerHTML = output;
clearInterval(timer);
}
else {
timeparts = [Math.floor(timeleft/60000),Math.floor(timeleft/1000)%60];
if( timeparts[1] < 10) timeparts[1] = "0"+timeparts[1];
elem.innerHTML = "Time left: "+timeparts[0]+":"+timeparts[1];
}
},250); // the lower this number, the more accurate the timer. 250 recommended
}
这将更有效地工作,因为它使用函数而不是依赖于eval
(这是将字符串传递给setTimeout
的情况)。此外,它使用增量时序来计算剩余时间 - 这是因为指定1000ms不准确。它依赖于即时处理的代码,而不是。
答案 1 :(得分:0)
首先7200秒= 120分钟而非20分;
现在关于20分钟:XX秒
var remMinutes = Math.floor(seconds / 60);
var remSeconds = seconds - (remMinutes * 60);
document.getElementById(elID).innerHTML = (seconds==0) ? output : 'Time until link appears: ' + remMinutes + "minutes and "+remSeconds+" seconds";
或者如果您希望输出为MM:SS
然后使用它:
document.getElementById(elID).innerHTML = (seconds==0) ? output : 'Time until link appears: ' + remMinutes + ":"+remSeconds;
答案 2 :(得分:0)
提醒一下,您不应该依赖于此以获得高安全性,有人可以轻松阅读源并找出链接。即使你对它进行模糊处理,如果浏览器可以解码它,那么一个坚定的人也可以。
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);
}
}
然而最好使用setInterval
而不是setTimeout
重新编写它。这是因为计时器不可靠且timer delay length is not guaranteed。执行setTimeout(something, 1000)
可能会在一秒后执行something
,或者在此之后的某个时间执行something
。它可能只有几毫秒,但在任何大量的时间内它都会加起来。
甚至像an alert
box will stop your setTimeout
based countdown那样简单!下面的代码每半秒通过重新计算每次运行的秒数来更新计数器。我们仍然可以使用setTimeout
执行此操作,但setInterval
更适合此工作。如果浏览器由于某种原因而陷入困境setInterval
只会放弃一些执行而不是试图追赶。这很好,因为它重新计算每次运行时留下的时间。这也意味着如果弹出alert
,也无关紧要。
在每次运行时不计入setTimeout
s序列递减计数器的另一个好理由是,在我们现代的标签式浏览器中,背景标签通常有timer resolution lowered,这也可以由于laptop power managment而发生。通常这意味着从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);
}
您可能已经注意到,在我提出的两个解决方案中,我在计算不同时间组件时使用了remainder operator。我这样做是因为使用remainder operator is faster而不是乘以将分钟作为秒,然后减去。您可能还注意到我的代码使用了严格的相等/不等式comparison operators ===
和!==
而不是==
和!=
。这种编码风格不仅会使JSLint hurt your feelings更少,而且会稍快一些。
在第二个更好的解决方案中,变量lastCount
存储上一次执行剩余的总秒数。由于代码将每秒运行一次以上,因此查看自上次以来结果是否已更改很有用。如果没有,我们就不用再做了。我们不必计算分钟数,更重要的是我们不必触及DOM,因为DOM access is slow。