`

理想Web倒计时器的设计与实现

 
阅读更多

1 引言
    使用倒计时,可以让用户清楚地了解离特定事件还剩余多少时间,因此在抢答系统、在线考试系统、节日倒计时等应用中都使用到倒计时。在Web应用中,一般使用JavaScript来设计倒计时程序。JavaScript中的setInterval()函数可以作为定时器,每隔一段时间执行指定的事件,但是这种定时器由于运行环境的限制,一旦用户刷新页面或关闭页面再打开,倒计时器又会重新计时,另外,由于JavaScript运行速度较慢,自身运行要占用一定时间,这种倒计时器也很难做到精确计时。
普通倒计时器的缺陷主要表现在以下几个方面:
    ①页面刷新后重新开始倒计时。
    ②面关闭再打开后重新开始倒计时。
    ③无法做到全部客户端同步。
    ④计时不精确,无法对自身进行校正。
    ⑤一旦客户端修改了计算机时钟,倒计时将会失败。
    普通倒计时器之所以存在以上问题,究其原因,在于下面几个方面:
    ⑴定时器设计技术。Web页面中的定时器使用JavaScript进行设计,由于HTTP连接不是一种持续连接,完成用户请求后,连接立即关闭,JavaScript的这种运行环境就决定了它不能记录用户的状态,每当页面刷新或页面关闭再打开后,相应JavaScript的变量会重新进行初始化,表现为倒计时重新计时。
    ⑵ JavaScript的运行速度。JavaScript以解释方法执行,运行速度较编译型语言慢。倒计时器设计时一般会使用到setInterval(function,interval)函数作为定时器,其中,interval为定时器间隔,单位为毫秒,function为定时器每隔interval指定的时间间隔触发的动作。如果function中含有复杂运算,并且由于JavaScript的执行速度较慢,定时器就会被拖慢,例如定义的间隔为1000ms,实际运行的间隔可能为1100ms,这样整个倒计时器的精度就会受到影响。
    ⑶ Web页面的随机请求方式。由于用户的请求是随机的,不可能要求所有用户在同一时间打开页面进行倒计时,所以无法做到所有客户端的倒计时同步。
2 防刷新防关闭自校正的倒计时器设计思路
    单纯使用客户端页面中的JavaScript无法设计出理想的Web倒计时程序,必须把动态脚本技术与客户端的JavaScript结合起来才可以实现符合要求的倒计时器。
    由于客户端显示的时间各不相同,所以不能作为倒计时器的时间参考,否则无法实现所有客户端的倒计时同步,但在B/S系统中,服务器的时间对于每一个客户端来说都是一致的,我们可以把服务器的时间作为倒计时参考时间,实现所有客户端的同步倒计时。
    在动态脚本语言(ASP、PHP、JSP)中可以很方便地取得服务器的当前时间。对于倒计时程序来说,都要指定一个结束时间,可以通过计算出一个服务器当前时间和结束时间之间的时间间隔,这个时间间隔反映了当前服务器时间离倒计时结束时间还有多长时间,无论用户怎样刷新、关闭再打开页面,计算出的这个时间间隔都是与客户端一致的,这样就避免了刷新、关闭再打开后倒计时器重新计时的问题。
    由于JavaScript是一种解释型语言,执行速度较编译型语言慢,每次执行setInterval()函数时每次都会产生一个很小的误差,虽然这个误差很小,但是这些小误差积累起来后却不容忽视,会严重影响倒计时器的精度,进而影响到客户端的同步。虽然各个客户端上的时钟各不相同,但是,我们可以认为所有客户端计算机的时钟步进是一致的,即A计算机时钟产生的1秒时间间隔与B计算机时间产生时间间隔是相同的,所以,我们可以把客户端计算机时钟作为观察倒计时器快慢的参照物,做出setInterval()函数的实际执行时间间隔与本地客户机时钟流逝时间间隔的差值,以这个差值作为反馈,修改setInterval()函数的执行间隔,从而达到自校正的目的,实现倒计时器的精确计时。
    另外,在使用上述自校正方法时,我们要考虑到在定时器执行时,客户修改了本地时钟的情况。一般情况下,我们得到的反馈差值不会太大,这里把1000ms作为阈值,一旦得到的差值大于1000ms,程序会认为客户修改了本地计算机时钟,停止自校正。仍使用原来的间隔时间,这样便解决了这个问题。
3 代码实现
    根据以上的设计思路,使用JSP作为动态脚本语言,实现了一个防刷新、防关闭、自校正、客户端调节时钟不敏感的倒计时器。该倒计时器由两个文件组成,djs.js中为JavaScript倒计时器的主体,实现倒计时功能;djs.jsp中获取服务器时间,调用djs.js中的start()方法开始倒计时,并显示出倒计时结果。
/ *****  djs.jsp  ***** /
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%
  SimpleDateFormat dfs = new SimpleDateFormat ("yyyy- MM-dd HH:mm:ss");
  java.util.Date begin=new Date();
  java.util.Date end = dfs.parse("2007-08-19 23:37:00");
  long l=end.getTime()-begin.getTime();
  long day=l/(24*60*60*1000);
  long hour=(l/(60*60*1000));
  long hour2=(l/(60*60*1000)-day*24);
  long min=((l/(60*1000))-day*24*60-hour2*60);
  long s=(l/1000-day*24*60*60-hour2*60*60-min*60);
  String interval=hour+":"+min+":"+s;
%>
剩余时间:<span id="clock"><%=interval%></span>
<script type="text/javascript" src="djs.js"></script>
<script language="Javascript">
run();
</script>
 
/****   djs.js  *****/
var counter,startTime,normalelapse = 1000,nextelapse = normalelapse,start =clock.innerText,timer = null;
var alert_time="00:05:00",finish = "00:00:00";
 
function run() {
  counter = 0;
  startTime = new Date().valueOf();  // 初始化开始时间
  // nextelapse是定时时间,初始时为1000毫秒
  // 注意setInterval函数: 时间逝去nextelapse(毫秒)后,onTimer才开始执行
  timer = window.setInterval("onTimer()",nextelapse);
}
 
function stop() { window.clearTimeout(timer);}   // 停止运行
window.onload = function() { }
function onTimer(){  // 倒计时函数
 if(start==alert_time) { alert("还有5分钟结束,请做好结束准备!");}  //剩余5分钟时,提示警告信息
if (start == finish) { //倒计时结束
  window.clearInterval(timer);
  alert("倒计时结束!");
  return;
}
 
var hms = new String(start).split(":");
var s = new Number(hms[2]);
var m = new Number(hms[1]);
var h = new Number(hms[0]);
  s -= 1;
  if (s < 0) {  s = 59;  m -= 1; }
  if (m < 0){  m = 59;  h -= 1; }
var ss = s < 10 ? ("0" + s) : s;
var sm = m < 10 ? ("0" + m) : m;
var sh = h < 10 ? ("0" + h) : h;
start = sh + ":" + sm + ":" + ss ;  //显示倒计时
clock.innerText = start;
window.clearInterval(timer); // 清除上一次的定时器
 
// 自校验系统时间得到时间差,并由此得到下次所启动的新定时器的间隔时间nextelapse
counter++;
var counterSecs = counter *1000;
var elapseSecs = new Date().valueOf() - startTime;  //已经经过的秒数
var diffSecs = counterSecs - elapseSecs;
 
//如果误差在1秒之内,则可以接受
//否则认为客户端用户调整了系统时间,不再进行定时器误差调整,仍使用默认值1000ms
if (Math.abs(diffSecs)<1000)  { 
nextelapse = normalelapse + diffSecs;
      }
 else
        nextelapse=normalelapse;
 
// 启动新的定时器
timer = window.setInterval("onTimer()",nextelapse);
}
4 结束语
    上述代码使用JSP作为动态脚本来实现,如果使用其它动态脚本语言,只需要修改取得当前服务器时间与结束时间的时间间隔片段即可,在此不再赘述。
以上实现的防刷新、防关闭、自校正、客户端修改时钟不敏感的倒计时程序已在笔者设计的在线考试系统中实现,项目实践证明,该倒计时器可以满足以上性能要求,在类似的Web应用中同样有着很好的参考价值。

分享到:
评论
1 楼 on_rain 2011-12-15  
***************
var elapseSecs = new Date().valueOf() - startTime;  //已经经过的秒数
****************
关键一点,你这还是用客户端时间去进行校验的,用户调一下机器时间你的这个倒计时就没用了

相关推荐

    理想Web倒计时器的设计与实现.doc

    "理想Web倒计时器的设计与实现" 本文总结了理想Web倒计时器的设计与实现,解决了传统倒计时器的缺陷,如页面刷新后重新开始倒计时、面关闭再打开后重新开始倒计时、无法做到全部客户端同步、计时不精确、无法对自身...

    PPT演讲倒计时器V2.2(C#WPF开发)

    总之,【PPT演讲倒计时器V2.2(C# WPF开发)】是一个体现C#编程技巧和WPF UI设计能力的应用实例,它展示了如何利用现代技术为办公场景提供实用且高效的支持。对于学习C#和WPF的开发者来说,这是一个值得研究的项目,...

    网站正在建设小屏倒计时模板

    倒计时功能的实现离不开CSS3的支持,通过CSS3的动画和过渡效果,可以实现数字动态更新和计时器的流畅显示。此外,滑动切换的“关于我们”页面也利用了CSS3的滑动效果,使得页面在小屏上的交互更为直观和顺畅。 三、...

    CountDownjs是js写的倒计时工具函数以及类

    根据项目的具体需求,开发者可以调整这些参数,以实现理想的倒计时效果。 总的来说,CountDown.js为JavaScript开发者提供了一个轻量级且易于使用的倒计时工具,可以帮助他们轻松地在网页上创建各种倒计时功能,同时...

    健身房上线倒计时模板

    【健身房上线倒计时模板】是...总之,【健身房上线倒计时模板】是一个全面的前端解决方案,它简化了网页制作过程,提供了吸引眼球的设计,并且通过技术手段确保了时间信息的准确展示,是健身房进行线上宣传的理想工具。

    jQuery多功能秒表闹钟计时器插件.zip

    这些特性使得jQuery成为实现计时器和闹钟功能的理想选择。 这个jQuery插件的设计目标是提供一个灵活、易用的时间管理解决方案,适用于多种应用场景。秒表功能可以记录时间流逝,闹钟功能则可以在指定时间发出提醒,...

    HTML5创意圣诞节主题模板是一款基于CSS3+HTML5实现的响应式圣诞节倒计时模板下载。_html网站模板_网页源.rar

    在这款模板中,CSS3的过渡(transitions)、动画(animations)和变形(transforms)被广泛使用,以创造平滑的过渡效果和动态的倒计时计时器。同时,CSS3选择器提供了更精细的控制,让开发者可以更加精确地定位和...

    countdown_timer:倒数计时器项目

    在`&lt;body&gt;`中,我们将编写倒计时器的具体内容。 倒计时器的核心部分是时间的显示。HTML可以使用`&lt;div&gt;`标签来创建可自定义样式的容器,每个容器对应一个时间单位,例如`&lt;div class="hours"&gt;`、`...

    chessTimer:角象棋计时器

    《JavaScript实现的角象棋计时器——深入解析与应用》 在当今的棋类比赛中,计时器已经成为不可或缺的一部分,它不仅确保了比赛的公平性,也为对弈双方提供了紧张刺激的比赛氛围。角象棋计时器是针对角国际象棋设计...

    uniapp好看的登录页面

    - 在某些场景下,如验证码发送后,登录页面可能需要显示一个倒计时器。uniapp可以结合`setTimeout`或`setInterval`函数实现这个功能。创建一个状态变量记录剩余时间,然后每秒更新显示,当倒计时结束时触发相应操作...

    信息技术会考Frontpage复习

    比如,通过表单收集用户信息,或使用计时器实现倒计时功能。 8. **链接与导航**:建立内部链接、外部链接和书签,确保用户在网站内顺畅浏览。同时,创建面包屑导航和下拉菜单,提高网站的导航性。 9. **预览与发布...

    meteor-countdown:Countdown.js v2.5.2 的流星包装器

    在现代Web开发中,计时器功能是常见的需求,无论是倒计时、定时任务还是时间显示,都需要准确且易用的计时库。本文将深入探讨基于Meteor框架的`meteor-countdown`包,它是一个针对`Countdown.js` v2.5.2的包装器,...

    pomodoro-clock:免费Code Camp Pomodoro Clock项目

    3. `script.js`: JavaScript文件,实现计时器功能的逻辑。 四、计时器实现 1. 初始化计时器:根据Pomodoro技术,初始化时间为25分钟。 2. 倒计时逻辑:使用`setInterval`函数每隔一定时间更新时间显示,直到达到0。...

    POLAR VANTAGE V2用户使用说明书.pdf

    16. **训练功能**:开始训练、计划训练、多运动训练等,提供实时数据和反馈,支持间隔计时器、倒计时计时器、心率、速度/配速和功率区间的锁定,以及分段记录,方便用户进行高效训练。 17. **重启和重置**:当遇到...

    TBS-Timer:由Ben Anderson @ Acidic为TBS-NZ创建

    1. **计时器功能**:TBS-Timer的核心功能可能是设置并启动倒计时,以便在排练过程中精确控制时间。这可能涉及使用JavaScript的`setInterval`或`setTimeout`函数来实现定时任务。 2. **界面设计**:计时器的用户界面...

    WordPressphp支付宝插件v1.0免费版

    这可能是指商品促销或限时优惠的计时器,可以增加紧迫感,促使潜在客户快速做出购买决定。这种营销策略在电商领域被广泛使用,能够有效提高转化率。 在后台,该插件提供了一个专门的配置页面,允许管理员轻松开通和...

    tabata.js:可配置的间隔定时器

    3. **事件回调**:库可能会提供事件触发机制,比如在每个工作阶段开始和结束时触发特定的回调函数,允许开发者添加自定义的行为或反馈,如播放声音、显示倒计时等。 4. **暂停/恢复功能**:用户应该能够随时暂停和...

Global site tag (gtag.js) - Google Analytics