现在很多网站都在做秒杀产品,其中最重要的一个环节就是倒计时。
关于倒计时,有以下几点需要注意:
1.应该使用服务器时间,而不是本地时间(本地时间存在时区不同、用户自行设置等问题)。
2.应该考虑耗时的网络传输。
3.获取时间时,可以直接从AJAX的响应头中读取(由getResponseHeader('Date ')获取),服务器不需要写时间来生成脚本。
流程分析:
1.从服务器读取时间戳后开始计时,不考虑网络传输的时间消耗;
图中标签如下(以上时间线采用标准时间,与服务器和页面时间无关):
Start——页面项目服务器发起AJAX请求的时间。
Www_start——服务器响应页面请求并向页面返回时间戳的时间。
Pc_start——页面接收服务器返回的时间戳并开始计时。
Www_end——服务器倒计时结束时间。
Pc_end——页面倒计时结束,也是用户在倒计时结束时点击按钮的时间。
End——服务器接收用户点击信息的时间。
可以看出,即使用户在倒计时结束的时刻(即尖峰开始的时刻)立即点击鼠标,也会晚于抓拍开始的实际时间(www_end,即服务器倒计时结束的时间)(很容易看出,这个时间差正好等于pc_start-start,即AJAX从开始发送到接收响应信息所花费的时间)。如果一些专家在页面倒计时结束前使用脚本发送请求,其他用户会损失很多。因此,我们应该解决时间误差的问题。
2.为了解决时间错误的问题,我们将页面倒计时时间缩短了一个小的量(从上面的分析可以得出,这个小的量正好等于pc_start-start),这样在倒计时结束时用户发送给服务器的抓拍信息正好在服务器倒计时结束时收到:
图中标注与Pic.1相同(时间轴采用标准时间,与服务器和页面的时间无关),新增的两个标注含义如下:
Old_pc_end——是pc_end不处理网络传输时间的时间。
Old_end——是不处理网络传输时间的结束时间。
从Pic.2可以看出,耗时的网络传输造成的时间误差已经通过“pc_start-start提前倒计时结束时间”得到了完全补偿。但它解决了耗时的网络传输带来的错误问题,以及用户的电脑时间与服务器时间不同的问题。让我们继续下面的讨论。
3.用户的计算机时间和服务器时间之间肯定有差别,甚至是几个时区。如何解决这个问题?该方法的要点如下:
A.当页面收到服务器返回的时间戳www_t时,会立即开始计时。
B.当页面收到服务器返回的时间戳www_t时,立即计算时间差t=newdate()。gettime ()-www _ t * 1000介于本地时间和服务器返回的时间戳之间。
C.新日期()。getTime()仍然用于计时,而不是setInterval()(计时器不稳定,误差大),但时间的显示和程序的逻辑必须基于本地时间和上一步(b)中得到的时间偏差t。
结论要点:
页面从收到服务器响应的时间戳开始计时,应该减去AJAX从发送到接收所花费的时间。计时过程由当地时间(当地时间-时间偏差)实现。
如有任何问题或建议请留言,谢谢!
Javascript提示:同步服务器时间,同步倒计时
看到网上有人问如何在页面上同步显示服务器时间的问题。事实上,有几种方法可以实现这一点。可能大部分人马上就认为可以用Ajax每秒请求服务器,然后在页面上显示服务器获得的时间。虽然可以做到,但是有一个很大的问题,就是每秒都要请求服务器,所以如果用户多了,服务器就会崩溃(内存占用率会很大)。因此,在我看来,这种方法是不可行的。我在这里给出一个解决方案,可以同步服务器时间,同步倒计时,但是不占用服务器太多资源。下面我将写实现的想法
第一步,当用户第一次浏览页面时,服务器首先获取当前时间并将其显示在页面上(例如,以ID显示在timebox span中)
第二步是设置每秒计算一次的新时间(新时间以服务器时间为初始值,然后每秒累加一秒生成新时间)
第三步,显示第二步计算的时间
是不是很简单,用一句话总结:以服务器时间为初始值,然后在页面上每秒自动累加生成一个新的时间,这样就可以和服务器时间同步,误差基本在几秒之内。应该没问题。让我们看看实现的代码:
span ID=' Timebox ' 11:21336055/span//Script Type=' text/JavaScript ' $(function(){ var o time=$(' # Timebox ');var ts=oTime.text()。split(': ',3);var tnums=[parseInt(ts[0]),parseInt(ts[1]),parseInt(ts[2])];setInterval(function(){ tnums=getNextTimeNumber(tnums[0],tnums[1],tnums[2]);showNewTime(tnums[0],tnums[1],tnums[2]);}, 1000);函数showNewTime(h,m,s) { var timeStr=('0' h.toString())。substr(-2)' : '(' 0 ' m . ToString())。substr(-2)' : '(' 0 ' s . ToString())。substr(-2);otime . text(timeStr);}函数getNextTimeNumber(h,m,s){ if(s==60){ s=0;} if(s==0){ if(m==60){ m=0;} } if(m==0){ if(h==24){ h=0;} }返回[h,m,s];} });/script代码很简单,这里就不解释了(我上面只显示小时和分钟,还可以添加日期,并且当h==0时,可以直接从服务器获取日期或完整时间作为时间校对)。不懂的可以在下面评论,我会及时回复。然后,按照这个思路,就可以实现同步倒计时了。首先,解释一下什么是同步倒计时,就像尖峰一样。设置一个结束时间,然后计算当前时间和结束时间之间的间隔,并确保不同电脑和浏览器上显示的倒计时时间相同。实现代码如下:
!DOCTYPE htmlhtmlhead标题同步倒计时/title脚本类型=' text/JAVAScript ' src=' http : jquery-1。4 .4 .量滴js '/script/head body span id=' time box ' 1天00时00分12秒/span!-假设:1天00时00分12秒是从服务器获取的倒计时数据-脚本类型=' text/JavaScript ' $(function(){ var tid=setInterval(function(){ var oTimebox=$(' # time box ')));var SyTime=otimeBox。text();var total sec=getTotalSecond(SyTime)-1;if(total sec=0){ otimebox。文本(GetNewsytime(总秒));} else { clearInterval(tid);} }, 1000);//根据剩余时间字符串计算出总秒数函数getTotalSecond(time tr){ var reg=/ d/g;var time nums=new Array();while((r=reg。exec(timetr))!=null){ time nums。push(ParSeint(r));} var秒=0,I=0;if(时间单位。长度==4){秒=时间nums[0]* 24 * 3600;I=1;}秒=时间nums[I]* 3600时间nums[I]* 60时间nums[I];第二次返回;} //根据剩余秒数生成时间格式函数getNewSyTime(秒){ var s=秒% 60;秒=(秒-s)/60;//最小var m=秒% 60;sec=(sec-m)/60;//小时var h=秒% 24;var d=(秒-小时)/24;//day var systemtr=' ';if(d ^ 0){ SyTiME str=d . ToString()'天;} SyStemTr=(“0”h . ToString()).substr(-2)'时(“0”m . ToString()).substr(-2)'分(“0”s . ToString()).substr(-2)'秒;返回SyStemTimeStr} });/脚本/正文/html为了保证倒计时的精确度,我采用了先将倒计时时间间隔统一计算成秒,然后减一秒再重新生成时间格式,当然也可以按照上面时间同步的例子,直接进行时间减少,方法很多,我这个不一定是最优的,欢迎大家交流,谢谢!