这篇文章发布于 2010年07月27日,星期二,17:21,归类于 JS实例。 阅读 248618 次, 今日 2 次 55 条评论
by zhangxinxu from https://www.zhangxinxu.com
本文地址:https://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
三、使用
倒计时其实就是Date类的一些计算与处理,主要是些繁琐的工作。为了省掉他人的功夫以及方便后来的使用,我已经将倒计时主要处理方法封装起来了。方法名为:fnTimeCountDown(参数1, 参数2)
。
具体使用如下,首先,调用倒计时js脚本,您可以在页面的任何位置嵌入这段脚本:
<script type="text/javascript" src="https://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);
这段实例代码所产生的效果如下所示:
0时 0分 0秒
如果现在还没有到2030年,则您应该可以看到上面秒前面的数值在不停的倒计时。
需要注意的是,参数2的对象集不支持jQuery对象,只能是DOM对象,如果您需要支持jQuery对象,需要修改原js方法中的innerHTML为jQuery的html()或是text()方法。
最后,提供下js脚本的下载,您可以狠狠地点击这里:timeCountDown.js(1.75K, 右键 – [目标|链接]另存为)
四、简短的结语
此脚本只是个人简单测试了下,且js功力尚浅,难免还存有bug或是不准确之处。如果您发现了,欢迎指正,不甚感谢。也欢迎各种形式的讨论与交流。
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[https://www.zhangxinxu.com]
本文地址:https://www.zhangxinxu.com/wordpress/?p=987
(本篇完)
- 精简高效的CSS命名准则/方法 (0.316)
- 完善:HTML5表单新特征简介与举例 (0.316)
- JavaScript实现图片幻灯片滚动播放动画效果 (0.190)
- jQuery - 鼠标经过(hover)事件的延时处理 (0.186)
- CSS3+js实现多彩炫酷旋转圆环时钟效果 (0.178)
- web上渐进使用jQuery Mobile中animate相关CSS (0.158)
- 3种纯CSS实现中间镂空的12色彩虹渐变圆环方法 (0.158)
- canvas实现任意字符图形的打点或连线动画 (0.158)
- JavaScript实现新浪微博文字放大显示动画效果 (0.052)
- js面向数据编程(DOP)一点分享 (0.052)
- 观点:不要太依赖JavaScript库 (RANDOM - 0.008)
还有33年08月26天19小时22分08秒
if(o.sec){
o.sec.innerHTML = f.dv().sec;
}
if(o.mini){
o.mini.innerHTML = f.dv().mini;
}
if(o.hour){
o.hour.innerHTML = f.dv().hour;
}
if(o.day){
o.day.innerHTML = f.dv().day;
}
if(o.month){
o.month.innerHTML = f.dv().month;
}
if(o.year){
o.year.innerHTML = f.dv().year;
}
这段这样写是不是更好些?
for (var i in o) {
o[i].innerHTML = f.dv()[i];
}
大神,等你老了走不动了,打开页面一看,倒计时还继续呢~~~
感谢!!!
取整用parseInt好点,时间这些不存在上舍下舍
好厉害。
如果页面有多个 地方需要显示倒计时,怎么做使用?
改了本地时钟,倒计时就变了。
jQ 插件就好了 厉害!
你好,张大哥,能把http://www.zhangxinxu.com/wordpress/?p=987完整的代码奉献下吗?我是PHP的不怎么懂js。谢谢
不显示月跟年 天数不正确
比如我是到2013年 天数还只是几天
张哥,您这个貌似通用性不强啊,月份按30天算,那2月份呢?1,3,5,7,8,10,12份呢?貌似就不准确了哦~
发现站长是个很有才的人,这段时间我得下定决心认真学学JQ了
下面的代码拷回去,放到网页上去,马上可以用。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);
不错!
为什么我运行代码的时候,没有时间啊?只有时 分 秒?
如何把剩余的年和月变成天呢!!!急救啊
还有一个问题,就是说 隐藏的时间为什么就不显示了
比如说我隐藏了“月” 那样子在“日”上应该加上才对呀 ,要不然 这个时间 显示很有局限的
很不错,我找了一下午没有找到合作的 相对来说 张哥这个是很不错的, 能实现 一页多次调用
如果客户在本地电脑调整了一下时间,那就出现问题了,明明团购时间已经过了,但是还是可以团购!
我明白了,原来是没有显示月那个字段
很好,很给力
呃,我实在是纳闷了,今天是2011年7月25日,DEMO上的到期时间是2050年7月30日,而倒计时显示的是39年00月29天……25日跟30日隔了29天?我不解了……
大哥我也做到个倒计时功能,发现个问题,(IE下)页面打开后右击鼠标的菜单,菜单弹出来后,时间就停止了,给JS加的断点也没有进, 是不是ie右击出来的菜单阻塞了JS?不晓得要怎么处理了
我想做个团购一个页面多个团购,并且多个倒计时进行。可我循环出来的是第一个倒计时正常,而后面的却没啥反映了,我知道这是变量问题.应该怎么做呀。QQ:44404234,请回复,我用的是ASPX
你好,我是一个地地道道的菜鸟,我非常喜欢你的这个倒计时作品,我想问一下,怎么在html写代码实现?能不能给一个全的?有点急···谢谢你·
不好意思,这么麻烦你···
多谢。找了很久了。很详细!
这个只读本地时间的是不可信的,要读服务器的时间才是最佳的做法,假如用户更改一下本地的日期,这个倒计时就没有意义了。
大哥 脚本下载了 不知道怎么用啊
好东西,我用了 不错。。可以做个扩展功能,例如 倒计时数字利用调用样式背景的方法 就可以换成各种 艺术字了。。不过思路就要变一下
这个确实是很实用,但是要有点功底才行啊~~~
我想问下future.getTimezoneOffset() * 60,这段怎么理解呢。两者的时间毫秒差为什么要加上这段,能否解答下。谢谢。。
同问+1
//程序并非直接使用new Date()取的客户端操作系统的时间,而是服务器的时间(Linux事先与某一台时间服务器校对过时间–为北京时间)。而产生问题的根源在于,服务器将它当前时间转成毫秒数后传递给客户端,客户端显示的时候没有进行时差修正。使用getTimezoneOffset()可解决这个问题,因为它返回的是格林威治时间与本地时间之间的时差,而使用new Date()得到的结果,还是相对于本地时间的显示,所以想真正实现客户端与服务器端显示的时间一致,需要做如下调整:先使用timezoneOffset()【此方法返回的是分钟】方法获取差值,这个就得到的是格林威治时间,而北京时间相对于它是需要再加上8小时的,也就是 8 * 60 = 480分钟。这样修正后,再调用格式化方法来显示时间就正常了。
date.getTime方法返回的是本地时间,getTimezoneOffset() * 60是为了修正不同地区的时间差,这也是楼主建议参数1使用UTC的原因,不知道我理解的对吗(不过getTimezoneOffset()返回的是与GMT的时间差,和UTC还是有些区别的)
谢谢旭哥的指点啊
还有一问,如果我这样写
else{
pms.sec = ″束″;
pms.mini = ″结″;
pms.hour = ″经″;
pms.day = ″已″;
pms.month = ″购″;
pms.year = ″团″;
}
这样不起作用呢,怎么解决呢?是我写的不对吗?
再谢旭哥!
旭哥,我要等多久才能等到你的回复啊
可怜我是个js白痴
@小鱼儿
Date.UTC(2030, 6, 27); 其中6不是表示6月份,而是7月份,是要加1的。所以你的到期其实还有一个月时间。
@ 团团,可以多次调用,但是你要用不同的 id 才可以
我现在更期待旭哥能解决一下月份一定要加1的问题,以及我上面的问题
不好意思,原谅我要刷屏了。最新发现!
var d = Date.UTC(2010, 12, 22, 0, 0);
这种情况下else不起作用,仍然从29开始倒计时
var d = Date.UTC(2010, 11, 22, 0, 0);
这种情况下else不起作用,成功!
旭哥,due>0的判断是否有问题啊
您可以用我上面两个数据试试看。
期待指点啊~~~
还是我,现在起作用了
但是同一个页面中多次调用,只有一个起作用,另外一个还是显示29天(多次调用,用的不同的id)
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天…….
如果时间到期
那么日会自动变成29
这个问题怎么解决呢?
亲爱的张大哥,帮忙解决一下吧
@小鱼儿 我之前已经提示过了,js里面有个到期的if判断,后面加个else,修改日期显示就可以了。
倒计时结束以后 天就会自动变成29,期待解决!
如果时间到期
那么日会自动变成29
这个问题怎么解决呢?
亲爱的张大哥,帮忙解决一下吧
最好可以实现这个功能,到期后,自动显示“已经到期”几个字样。那样就完美了。呵呵
期待答复啊
哇,我觉得脚本代码的写法可读性相当高,很不错。 同一页面至于多次调用的问题,我是用闭包解决的
不能多次调用
有什么办法可以在一个页面里面显示多个不同的倒计时呢?
能在倒计时结束后触发一个动作吗?
可以的,原脚本只有if(dur > 0){}的判断,如果时间结束,则dur为为0,所以,在后面加个else{…}就是倒计时结束触发的动作了。
帅哥~为什么月份要减一个月才能正常显示当月呢 不能不减一个月吗~~
谢谢了。。。不错嘛
我以前也有研究这方面的
啊,不让贴,那就麻烦您说一下这种用法的名字吧,谢谢啦,我经常在jQuery的插件里看到类似的用法,麻烦了!
new document
全部贴上了,希望能方便您排错,我第一次用这种变量 = { a:b,c:d… }这样的格式,希望能说出这个用法的名字,我好自己找些资料,谢谢啊!