一:前言
事情发生在刚刚完成的11月份超值抢活动,添加了倒计时功能,并且考虑到每个手机的本地时间不一致,为了严谨期间,索性把当前时间通过服务器来传递给前端界面。
二:代码实现
功能实现过程非常顺利,当距离开抢时间大于一个小时的时候,不显示分秒,直接显示具体时间;小于一小时,直接进入逐秒刷新的时刻倒计时。
主要是两个时间点,一个是var Now = new Date("time of Service")代替手机端的本地时间new Date();另外一个是End的时间点,绑定在dom元素time的startTime属性值中,也同样是由服务器设置的开抢时间
DOM结构:
<section id="133" class='gray'>
<div class="item">
<div class="left">
<a href="javascript:void(0)" ><img src='/weixin/resource/images/loading.png' data-src="http://coupon.96225.com/coupon/upload/20151214154636.png"></a>
<article style="display:none">
<h1 class='setover'>5折</h1>
<ul>
<li><span>现价:¥</span><i>¥</i></li>
<li>有效期至:2015-12-24</li>
</ul>
</article>
</div>
<div class="right">
<time startTime='2015-12-17 15:05:00.0'></time>
<a class="get01" ></a>
<p class='have'>剩100张</p>
<a class="detail"></a>
</div>
</div>
</section>
Js代码:
function reduceTime(){
var Now = new Date("2015/12/18 14:53:21"),
reduceTime_ = function(){
Now.setSeconds(Now.getSeconds()+1);
$('time').each(function(){
var End = $(this).attr('startTime');
End= new Date(temp);
var t =End.getTime() - Now.getTime();
if(t>0){
$(this).parent().find('.get01,.have').css('visibility','hidden');
var d = 0, h = 0, m = 0, s = 0, arr = [];
if(t>=0){
d=Math.floor(t/1000/60/60/24);
h=Math.floor(((t/1000/60/60)%24)-(d*24));
m=Math.floor(t/1000/60%60);
s=Math.floor(t/1000%60);
h += d*24;
arr=[d==0 ? '' : (d+'天'),h==0 ? '' : (h+'小时'),(m<10 ? ('0'+m) : m) +':',s<10 ? ('0'+s) : s];
}
if(parseInt(arr[0])>0||parseInt(arr[1])>0){
arr.splice(2,2);
}
$(this).html('<span style="color:#db5252;font-size:16px">倒计时</span> <br/>'+arr.join(''));
}else{
$(this).parent().find('.get01,.have').css('visibility','visible');
$(this).remove();
}
})
};
reduceTime_();
//轮询执行 抢购倒计时
setInterval(reduceTime_,1000);
}
reduceTime();
二:提交测试
由于功能比较简单,整个前端交互很快就顺利完成,使用自己的小米4手机自测无误之后,就直接把页面提交后台开发人员,自己埋头继续研究其它项目去了。
次日开发兄弟表示已经完成后台开发,而且使用他的三星手机测试成功。于是我简单地参与测了一下,确认成功之后,就把项目提交测试。坐等测试结果。我们的测试部门全是土豪,几乎都是水果6的手机,结果我们屁股还没坐热,测试就反馈过来,苹果手机里面根本没有倒计时功能,你们确定你们开发了这个功能吗?当时我们就震惊的掏出自己的屌丝机重新访问了一下测试地址,确定是有倒计时,然后让测试mm清空微信缓存再重新刷新下,可是最终他们也没看到倒计时,一个赤裸裸的操作系统bug,安卓正常,ios出错,而且这个bug直接切断了测试人员继续测试其它bug的去路。
三:bug分析、解决
拿到这个bug,我首先仔细审视了下自己的这段前端代码,代码本身逻辑应该正确,毕竟安卓下能成功显示。先映入自己脑海的是,后台传入的时间是否跟我自己期待的一致,带着这个疑问,在代码的中间插入了alert,在手机端无法使用console,转而使用弹窗模式来提示具体的节点信息。果然,拿到的服务器数据格式是:2015-12-18 12:00:00.0,项目是跑在Apach Tomcat里面,我一般在前端使用new Data(),传入参数的时候习惯使用2015/12/18 12:00:00格式,于是通过查阅相关资料-Javascript invalid date in iOS/Android 2.2,发现在安卓2.2以及ios系统下面,用2015-12-18这种横线模式初始化日期是会直接报invalid date的错误,Rhino开发也同样存在这个问题。而自己使用的小米4以及同事的三星手机刚好都是安卓4.x.x版本,已经升级到可以包容这种横线日期格式,不会报错;ios系统则继续保持严谨的格式,所以直接报错,倒计时无法出现。定位到问题就简单了,直接startTime = startTime.replace(/-/g,'/');直接把横线替换成斜杠,然后再跑一遍应该就OK了。结果改成试验的时候还是报错invalid date,后来仔细观察发现2015-12-18 12:00:00.0,后面多了一个小数点跟一个数字,从这个结果上看,这个数字估计是百毫秒单位,因为1000毫秒=1秒,原来安卓4.xx系统把百毫秒也合并进来了,最后,把后面的小数点和数字去掉之后,ios终于能正常出现倒计时了。
四:小结
不得不佩服IOS在代码方面的严谨性,也佩服安卓在不同版本升级中的容错性越来越好,各有各的好,多多学习,多多积累!
五:参考资料:Javascript invalid date in iOS/Android 2.2 , 苹果系统时间格式问题