1

我正在尝试制作一个倒数计时器,它的链接在 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 秒?

4

3 回答 3

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作用)。此外,它使用增量计时来计算剩余时间 - 这是因为指定 1000 毫秒是不准确的。它依赖于立即处理的代码,但事实并非如此。

于 2013-03-02T00:01:06.630 回答
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;
于 2013-03-01T23:21:54.103 回答
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);
    }

}

jsFiddle

但是setInterval,使用而不是重写它会是一个更好的主意setTimeout。这是因为定时器不可靠且定时器延迟长度无法保证。DoingsetTimeout(something, 1000)可能会在something一秒钟后执行,或者它可能something会在那之后的某个时间执行。它可能只会在这里和那里只有几毫秒,但在任何相当长的时间内它都会加起来。

即使是像盒子这样简单的东西也会alert停止你setTimeout的倒计时!下面的代码通过重新计算每次运行时剩余的秒数每半秒更新一次计数器。我们仍然可以使用 来做到这一点setTimeout,但setInterval更适合这项工作。如果浏览器由于某种原因陷入困境,setInterval只会放弃一些执行,而不是试图追赶。这很好,因为它每次运行时都会重新计算剩余时间。这也意味着如果alert弹出一个,也没关系。

另一个不依赖setTimeouts 序列在每次运行时递减计数器的好理由是,在我们现代的选项卡式浏览器世界中,后台选项卡的计时器分辨率通常会降低,这也可能是由于笔记本电脑的电源管理而发生的。通常这意味着从 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 访问速度很慢

于 2013-03-02T00:07:41.893 回答