倒计时器直到链接出现

时间:2013-03-01 23:13:37

标签: javascript countdown

我正在尝试制作倒数计时器,其中包含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秒呢?

3 个答案:

答案 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);
    }

}

jsFiddle

然而最好使用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);
}

jsFiddle

您可能已经注意到,在我提出的两个解决方案中,我在计算不同时间组件时使用了remainder operator。我这样做是因为使用remainder operator is faster而不是乘以将分钟作为秒,然后减去。您可能还注意到我的代码使用了严格的相等/不等式comparison operators ===!==而不是==!=。这种编码风格不仅会使JSLint hurt your feelings更少,而且会稍快一些。

在第二个更好的解决方案中,变量lastCount存储上一次执行剩余的总秒数。由于代码将每秒运行一次以上,因此查看自上次以来结果是否已更改很有用。如果没有,我们就不用再做了。我们不必计算分钟数,更重要的是我们不必触及DOM,因为DOM access is slow

相关问题