0

好吧,我正在尝试为此处看到的每个挑战重新创建倒计时: http ://www.bungie.net/stats/reach/globalchallenges.aspx

问题是如果你将我的倒计时原来的倒计时进行比较,会有大约 10-14 秒的差异,我只是不明白为什么?谢谢!

我正在使用他们的移动页面(查看源代码)中的源代码来获取到期时间。

<span id="wExpSeconds" title="1304330400000"></span>
<span id="dExpMilliseconds" title="1303984800000"></span>

这是我的倒计时页面的源代码:

<html>
    <head>
        <title></title>
        <style type="text/css">
        .stat{ font: 14px/18px Arial, Helvetica, sans-serif; color:#bbb; }
        .seconds{ color:#ff5f3c; }
        </style>
    </head>
    <body>

        <div id="countDownDiv"></div>

        <script type="text/javascript">
        function countDown(id, end, cur){
            this.container = document.getElementById(id);
            this.endDate = new Date(end);
            this.curDate = new Date(cur);


            var context = this;

            var formatResults = function(day, hour, minute, second){
            var displayString = [
                '<span class="stat">',day,'d </span>',
                '<span class="stat">',hour,'h </span>',
                '<span class="stat">',minute,'m </span>',
                '<span class="stat seconds">',second,'s</span>'
            ];
            return displayString.join("");
            }

            var update = function(){
                context.curDate.setSeconds(context.curDate.getSeconds()+1);

                var timediff = (context.endDate-context.curDate)/1000; 

                // Check if timer expired:
                if (timediff<0){ 
                    return context.container.innerHTML = formatResults(0,0,0,0);
                }

                var oneMinute=60; //minute unit in seconds
                var oneHour=60*60; //hour unit in seconds
                var oneDay=60*60*24; //day unit in seconds

                var dayfield=Math.floor(timediff/oneDay);
                var hourfield=Math.floor((timediff-dayfield*oneDay)/oneHour);
                var minutefield=Math.floor((timediff-dayfield*oneDay-hourfield*oneHour)/oneMinute);
                var secondfield=Math.floor((timediff-dayfield*oneDay-hourfield*oneHour-minutefield*oneMinute));

                context.container.innerHTML = formatResults(dayfield, hourfield, minutefield, secondfield);

                // Call recursively
                setTimeout(update, 1000);
            };

            // Call the recursive loop
            update();
            }

        countDown("countDownDiv",1304330400000, new Date().getTime());
        </script>
    </body>
</html>
4

1 回答 1

0
   <script type="text/javascript">
    function countDown(id, end, cur){
        this.container = document.getElementById(id);
        this.endDate = new Date(end);
        this.curDate = new Date(cur);

由于该函数不是作为任何对象的方法调用的,也不是用call()or调用的apply(),所以它的 this 关键字将引用全局对象。所以上面有效地为容器、endDate 和 curDate 创建了全局变量。

        var context = this;

请写出 1000 次:this 关键字不是上下文(也与作用域无关)。

         ...
         context.curDate.setSeconds(context.curDate.getSeconds()+1);

正如已经讨论过的,变量“context”是对全局对象的引用,它是由你调用函数的方式设置的。所以你在这里访问全局变量。

         ...
         // Call recursively
         setTimeout(update, 1000);

这是你的问题。这将在大约1 秒内调用更新。你的计数器运行的时间越长,它就会变得越不准确(它总是会在以后漂移)。

您应该每次都获得一个新的日期对象,查看毫秒,然后在下一整秒之后调用下一个超时(给它大约 30 到 50 毫秒以确保它只是在之后而不是之前)。这样你的计数器永远不会出现太多,即使是这样,它也会在每次调用时自行纠正。

And make sure you calculate the full count down each time, so if there is a lag of a few seconds you catch up again.

于 2011-04-28T03:34:25.370 回答