团购类网站倒计时的js实现

by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=987

一、如火如荼的团购网站

根据易观国际提供的统计数据,截至2010年6月,中国市场团购网站数量已经突破400家。国内团购潮从今年2月份开始出现,在4~6月出现高峰,尤其是今年5月,一些大的网站如爱帮网、开心网都加入到团购中来,F团、团宝、酷团、515团购、1288团购、拉手、24券、满座、窝窝、满堂网、糯米网、第一团购等也纷纷上线。预计年底,我国团购类网站的数量将达到1000多家,甚至有业内人士称“一天之内会有三到五家新的团购网站诞生”。俗称“千团大战”。

据说王兴的美团网上线4个月就盈亏平衡了,还有,貌似企鹅、点评也来插足了。

不过这类团购网站是死是活、孰好孰坏不管我鸟事,我所关心的是一些让我感兴趣的前端内容,比如说,这类团购网站的倒计时。
美团网倒计时 张鑫旭-鑫空间-鑫生活企鹅团倒计时张鑫旭-鑫空间-鑫生活点评团倒计时 张鑫旭-鑫空间-鑫生活

虽然有的横着睡觉,有的竖着休息,本质上都是一样的,一样的阿拉伯数字,一样的一秒一变化。本文内容就是展示如何在前端使用js实现倒计时的UI效果。

二、demo与效果展示

为节约时间,我就直接套用了企鹅团的界面作为demo的背景。因为是倒计时,所以需要一个固定的时间,为了n年后,某位仁兄打开demo页面依然在倒计时,所以我把倒计时时间设成了2050年7月30日中午12点整,还有40年才到,因为年代较长,所以有必要显示剩余年份与月份。所以,最后demo页面的效果如下图所示:
demo页面关键部位截图 张鑫旭-鑫空间-鑫生活

您可以狠狠地点击这里:团购倒计时demo

三、使用

倒计时其实就是Date类的一些计算与处理,主要是些繁琐的工作。为了省掉他人的功夫以及方便后来的使用,我已经将倒计时主要处理方法封装起来了。方法名为:fnTimeCountDown(参数1, 参数2)

具体使用如下,首先,调用倒计时js脚本,您可以在页面的任何位置嵌入这段脚本:

<script type="text/javascript" src="http://www.zhangxinxu.com/study/js/timeCountDown.js"></script>

然后,调用方法fnTimeCountDown(参数1, 参数2)即可,于是就可以实现倒计时效果了,很简单吧。

下面是重点了,就是关于这里的参数。参数1指的是截止的时间。我个人建议使用UTC()方法创建Date对象传递给Date构造函数。例如,Date.UTC(2030, 6, 27, 16, 34),表示的就是2030年7月27日161时34分0秒(月份需要加1),然后将这个参数替换“参数1”就可以了。具体来说就是:

var d = Date.UTC(2030, 6, 27, 16, 34);
fnTimeCountDown(d, 参数2)

关于参数2,有点小复杂。参数2是个对象,同时也是个对象集,是显示秒、分、时数值标签的DOM对象集合,里面的对象名是固定的,不可自己定义,否则没有效果的。考虑到扩展性,对象名从秒一直到年,具体如下:

{
     sec: 显示秒数值的标签对象,
     mini: 显示分钟数值的标签对象,
     hour: 显示小时数值的标签对象,
     day: 显示天数数值的标签对象,
     month: 显示月份数值的标签对象,
     year: 显示年数数值的标签对象
}

以上所有的参数都是可选的,如果哪个参数没有,则不显示时间变化,如果参数对应的DOM对象不存在,自然也没有数值变化的。如果是上面部分展示的团购倒计时的话,只要下面三个子对象就足够了:

{
     sec: 显示秒数值的标签对象,
     mini: 显示分钟数值的标签对象,
     hour: 显示小时数值的标签对象
}

举个例子吧,有三个标签,分别用来显示剩余的小时数,分钟数以及秒数的,其id分别是hour,mini,sec,如下所示:

<span id="hour"></span>时 <span id="mini"></span>分 <span id="sec"></span>秒

则第二个参数应该这么写:

var obj = {
     sec: document.getElementById("sec"),
     mini: document.getElementById("mini"),
     hour: document.getElementById("hour")
}

所以两个参数合起来就是:

var d = Date.UTC(2030, 6, 27, 16, 34);
var obj = {
     sec: document.getElementById("sec"),
     mini: document.getElementById("mini"),
     hour: document.getElementById("hour")
}
fnTimeCountDown(d, obj);

这段实例代码所产生的效果如下所示:
000

如果现在还没有到2030年,则您应该可以看到上面秒前面的数值在不停的倒计时。

需要注意的是,参数2的对象集不支持jQuery对象,只能是DOM对象,如果您需要支持jQuery对象,需要修改原js方法中的innerHTML为jQuery的html()或是text()方法。

最后,提供下js脚本的下载,您可以狠狠地点击这里:timeCountDown.js(1.75K, 右键 – [目标|链接]另存为)

四、简短的结语

此脚本只是个人简单测试了下,且js功力尚浅,难免还存有bug或是不准确之处。如果您发现了,欢迎指正,不甚感谢。也欢迎各种形式的讨论与交流。

原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=987

(本篇完)

标签: , , , , , , , , , ,

42 条评论 发表在“团购类网站倒计时的js实现”上

  1. 康康 说:

    new document

    全部贴上了,希望能方便您排错,我第一次用这种变量 = { a:b,c:d… }这样的格式,希望能说出这个用法的名字,我好自己找些资料,谢谢啊!

  2. 康康 说:

    啊,不让贴,那就麻烦您说一下这种用法的名字吧,谢谢啦,我经常在jQuery的插件里看到类似的用法,麻烦了!

  3. 百度优化 说:

    我以前也有研究这方面的

  4. 谢谢了。。。不错嘛

  5. 小脑 说:

    帅哥~为什么月份要减一个月才能正常显示当月呢 不能不减一个月吗~~

  6. rqyy 说:

    能在倒计时结束后触发一个动作吗?

  7. 张 鑫旭 说:

    可以的,原脚本只有if(dur > 0){}的判断,如果时间结束,则dur为为0,所以,在后面加个else{…}就是倒计时结束触发的动作了。

  8. 团团 说:

    不能多次调用
    有什么办法可以在一个页面里面显示多个不同的倒计时呢?

  9. Gyrate 说:

    哇,我觉得脚本代码的写法可读性相当高,很不错。 同一页面至于多次调用的问题,我是用闭包解决的

  10. 小鱼儿 说:

    如果时间到期
    那么日会自动变成29
    这个问题怎么解决呢?
    亲爱的张大哥,帮忙解决一下吧
    最好可以实现这个功能,到期后,自动显示“已经到期”几个字样。那样就完美了。呵呵
    期待答复啊

  11. 一样的问题 说:

    倒计时结束以后 天就会自动变成29,期待解决!

  12. 小鱼儿 说:

    如果时间到期
    那么日会自动变成29
    这个问题怎么解决呢?
    亲爱的张大哥,帮忙解决一下吧

  13. 张 鑫旭 说:

    @小鱼儿 我之前已经提示过了,js里面有个到期的if判断,后面加个else,修改日期显示就可以了。

  14. 小鱼儿 说:

    if(dur > 0){
    pms.sec = f.zero(dur % 60);
    pms.mini = Math.floor((dur / 60)) > 0? f.zero(Math.floor((dur / 60)) % 60) : “00″;
    pms.hour = Math.floor((dur / 3600)) > 0? f.zero(Math.floor((dur / 3600)) % 24) : “00″;
    pms.day = Math.floor((dur / 86400)) > 0? f.zero(Math.floor((dur / 86400)) % 30) : “00″;
    //月份,以实际平均每月秒数计算
    pms.month = Math.floor((dur / 2629744)) > 0? f.zero(Math.floor((dur / 2629744)) % 12) : “00″;
    //年份,按按回归年365天5时48分46秒算
    pms.year = Math.floor((dur / 31556926)) > 0? Math.floor((dur / 31556926)) : “0″;
    }
    else{
    pms.sec = “8″;
    pms.mini = “8″;
    pms.hour = “8″;
    pms.day = “8″;
    pms.month = “8″;
    pms.year = “8″;
    }
    return pms;

    ——————————–

    我是这样修改的,如果时间到期,就显示8天8小时8分8秒

    但修改后,JS貌似不起作用,仍然变成29天…….

  15. 小鱼儿 说:

    还是我,现在起作用了
    但是同一个页面中多次调用,只有一个起作用,另外一个还是显示29天(多次调用,用的不同的id)

  16. 小鱼儿 说:

    不好意思,原谅我要刷屏了。最新发现!
    var d = Date.UTC(2010, 12, 22, 0, 0);
    这种情况下else不起作用,仍然从29开始倒计时

    var d = Date.UTC(2010, 11, 22, 0, 0);
    这种情况下else不起作用,成功!

    旭哥,due>0的判断是否有问题啊
    您可以用我上面两个数据试试看。
    期待指点啊~~~

  17. 小鱼儿 说:

    @ 团团,可以多次调用,但是你要用不同的 id 才可以

    我现在更期待旭哥能解决一下月份一定要加1的问题,以及我上面的问题

  18. 小鱼儿 说:

    旭哥,我要等多久才能等到你的回复啊
    可怜我是个js白痴

  19. 张 鑫旭 说:

    @小鱼儿
    Date.UTC(2030, 6, 27); 其中6不是表示6月份,而是7月份,是要加1的。所以你的到期其实还有一个月时间。

  20. 小鱼儿 说:

    谢谢旭哥的指点啊
    还有一问,如果我这样写

    else{
    pms.sec = ″束″;
    pms.mini = ″结″;
    pms.hour = ″经″;
    pms.day = ″已″;
    pms.month = ″购″;
    pms.year = ″团″;
    }

    这样不起作用呢,怎么解决呢?是我写的不对吗?
    再谢旭哥!

  21. LQ 说:

    我想问下future.getTimezoneOffset() * 60,这段怎么理解呢。两者的时间毫秒差为什么要加上这段,能否解答下。谢谢。。

  22. 安检门 说:

    这个确实是很实用,但是要有点功底才行啊~~~

  23. 张涛 说:

    好东西,我用了 不错。。可以做个扩展功能,例如 倒计时数字利用调用样式背景的方法 就可以换成各种 艺术字了。。不过思路就要变一下

  24. 左右之旅 说:

    大哥 脚本下载了 不知道怎么用啊

  25. Edisontsai 说:

    这个只读本地时间的是不可信的,要读服务器的时间才是最佳的做法,假如用户更改一下本地的日期,这个倒计时就没有意义了。

  26. 如家 说:

    多谢。找了很久了。很详细!

  27. 小点儿 说:

    你好,我是一个地地道道的菜鸟,我非常喜欢你的这个倒计时作品,我想问一下,怎么在html写代码实现?能不能给一个全的?有点急···谢谢你·
    不好意思,这么麻烦你···

  28. yqy3483 说:

    我想做个团购一个页面多个团购,并且多个倒计时进行。可我循环出来的是第一个倒计时正常,而后面的却没啥反映了,我知道这是变量问题.应该怎么做呀。QQ:44404234,请回复,我用的是ASPX

  29. flysky1001 说:

    大哥我也做到个倒计时功能,发现个问题,(IE下)页面打开后右击鼠标的菜单,菜单弹出来后,时间就停止了,给JS加的断点也没有进, 是不是ie右击出来的菜单阻塞了JS?不晓得要怎么处理了

  30. 吉光片羽 说:

    呃,我实在是纳闷了,今天是2011年7月25日,DEMO上的到期时间是2050年7月30日,而倒计时显示的是39年00月29天……25日跟30日隔了29天?我不解了……

  31. dleung 说:

    很好,很给力

  32. 阿亮 说:

    我明白了,原来是没有显示月那个字段

  33. linzhuzhang 说:

    如果客户在本地电脑调整了一下时间,那就出现问题了,明明团购时间已经过了,但是还是可以团购!

  34. edayshop 说:

    很不错,我找了一下午没有找到合作的 相对来说 张哥这个是很不错的, 能实现 一页多次调用

  35. edayshop 说:

    还有一个问题,就是说 隐藏的时间为什么就不显示了

    比如说我隐藏了“月” 那样子在“日”上应该加上才对呀 ,要不然 这个时间 显示很有局限的

  36. cykjydxs 说:

    如何把剩余的年和月变成天呢!!!急救啊

  37. 西施 说:

    为什么我运行代码的时候,没有时间啊?只有时 分 秒?

  38. 其实这样麻烦的要死,像下面这样写,简单明了。 说:

    下面的代码拷回去,放到网页上去,马上可以用。IE,火狐等主流浏览器都兼容。

    function _fresh() {
    var endtime = new Date(“2011/11/3,17:00:00″);
    var nowtime = new Date();
    var leftsecond = parseInt((endtime.getTime() – nowtime.getTime()) / 1000);
    __d = parseInt(leftsecond / 3600 / 24);
    __h = parseInt((leftsecond / 3600) % 24);
    __m = parseInt((leftsecond / 60) % 60);
    __s = parseInt(leftsecond % 60);
    document.getElementById(“times”).innerHTML = “” + __d + “天 ” + “” + __h + “” + “小时 ” + “” + __m + “” + “分 ” + “” + __s + “” + “秒”;
    if (leftsecond <= 0) {
    document.getElementById("times").innerHTML = "抢购已结束";
    clearInterval(sh);
    }
    }
    _fresh()
    var sh;
    sh = setInterval(_fresh, 1000);

  39. 近墨者 说:

    发现站长是个很有才的人,这段时间我得下定决心认真学学JQ了

  40. 微笑小婷 说:

    张哥,您这个貌似通用性不强啊,月份按30天算,那2月份呢?1,3,5,7,8,10,12份呢?貌似就不准确了哦~

  41. jie 说:

    不显示月跟年 天数不正确
    比如我是到2013年 天数还只是几天

  42. gayayang 说:

    你好,张大哥,能把http://www.zhangxinxu.com/wordpress/?p=987完整的代码奉献下吗?我是PHP的不怎么懂js。谢谢

留下回复