DateQuery是本人些的一个时间操作类,类库的文档可在此查看:
一行JS搞定时间增删改、倒计时,来自类库:lv-js
这个类库本身是作为方便操作时间的对象,不过发布后看来,不少朋友对“倒计时”这个功能很感兴趣,所以这里我就围绕这个来说说这个类库的特性,在篇尾还会顺带提一提,新增加的walk方法,对于需要做日历、时间提醒等插件的朋友,很有帮助哟~
最简单的一个倒计时,核心代码:
setInterval(function() { lv.date().set('2015-11-12 11:00:20', true).get('g', true); }, 100);
上面代码的意思是设置一个截止时间为:2015-11-12 11:00:20 的DateQuery对象,每100秒取一次时间差。当然如果将上面代码如下优化,可能会更好哦:
// 先申明一个DateQuery对象 var date = lv.date().set('2015-11-12 11:00:20', true); // 每100毫秒获取一次时间差 setInterval(function() { date.set().get('g', true); // 注意这里的set哦,他会自动更新当前时间 }, 100);
具体方法请参考文档:http://levi.cg.am/archives/3690
提供一个在线演示:
后来一朋友提出这么一个需求:
于是当时给出了这么一个“理想”状态的代码:
// 初始时间是服务端给的哦,set的时间可以是固定值 var date = lv.date('2014-10-27 18:00:00').set('2014-11-27 18:00:00', true); // 每100毫秒递增时间 setInterval(function() { date.add(100).get('g', true); }, 100);
当然这仅仅是“理想”状态,实际使用过程中会有“延迟”,为什么会出现“延迟”。这里说下并非类库本身的BUG,而是在于这段代码设计的不太合理,并没有考虑setInterval的“延迟”时间,做个测试如下:
// 还是刚才那段代码 var date = lv.date('2014-10-27 18:00:00').set('2014-11-27 18:00:00', true); // 设置两个时间点 var test = lv.date(), test_aft; // 每100毫秒递增时间 setInterval(function() { date.add(67).get('g', true); // 将执行后的时间和执行前进行比较后 test_aft = lv.date(); console.log(test.diff(null, test_aft) - 67); test.set(test_aft); // 更新时间 }, 67);
以上代码拷贝放入chrome调试器中查看,你会发现没次setInterval回调都会延迟0-2毫秒的时间,累计后则会有较明显的“时间计算错误”
题外话:diff这个方法设计之初也单纯只是作为对比,设计出来后发现这个方法,还可以作为代码调试用途,例如:帮你统计代码执行时间、程序的效率等问题
很显然这样就不符合实际需求了,那如何做到“避免用户篡改时间”?这里我提供两个方法:
// 还是刚才那段代码 var date = lv.date('2014-10-27 18:00:00').set('2014-11-27 18:00:00', true), time = lv.date(); // 每100毫秒递增时间 setInterval(function() { // 每隔3分钟,向服务器发起请求进行效验 if (lv.date().diff(null, timg) > 18000) { // 这里的Ajax方法省略,大家可以通过jquery或其他方法实现 httpAjax('url', function(serverTime) { date.set(serverTime); // 从服务器上获取效验后的时间 time.set(); // 别忘记了同时更新本地时间 }); } date.add(100).get('g', true); }, 100);
当然这个方法非常占用资源,不建议这么实现
这个方法只效验结果,不效验过程,最终向服务器只提交一次请求来判断是否正常。使用的是“本地时间”,而非“服务器时间”,代码如下:
// 先申明一个DateQuery对象 var date = lv.date().set('2015-11-12 11:00:20', true), val; // 每100毫秒获取一次时间差 setInterval(function() { val = date.set().get('g', true); if (!val[0]) { // 这里的Ajax方法省略,大家可以通过jquery或其他方法实现 httpAjax('url', function(status) { !status && alert('您本地时间设置不正确'); }); } }, 100);
以上就是我提供的“倒计时防作弊”的方法,如果你有更好的解决方案,可以留言告诉我哦。
出了倒计时之外,使用这个类库,还能极大的方便设计日历,核心代码如下:
lv.date().walk('m', 'd', function() { console.log(this.get('Y-m-d 星期:') + ['日', '一', '二', '三', '四', '五', '六'][this.get('w')]); });
通过上面的方法,会将当前月份,以天为间隔单位,通过闭包的方式循环输出lv.date对象(剩下的,只需在闭包中通过get方法,输出指定时间格式)。
当然你也可以一次性输出2个月的时间、3个月的时间、一周的时间,这个随意,具体请查看文档:http://levi.cg.am/archives/3690
下面是我自己做的一个简单的日历,借用了jquery作为Dom操作:
您可能也喜欢: |
一行JS搞定时间增删改、倒计时,来自类库:lv-js |
用jQuery模仿新浪微博时间组件 |
php中时间轴开发,即显示为“刚刚”、“5分钟前”、“昨天10:23”等 |
PHP时间相减总结 |
PHP获取远程web服务器时间的代码 |
无觅 |