公司规定每日签到两次;日子太安逸了,有时候中午居然会忘记签到……
于是,笔者寻思写一个自动签到的脚本;每天指定两个签到时段,每次打开页面,先检测当前是否为签到时段,如果在签到时段,则检查cookie中记录的值,确认该时段是否已经签到过了,巴拉巴拉…… 具体细节见流程图:
其中第一步调用的getCheckTime用来检测当前是否为签到时间,并返回当前时间距下一个时段的毫秒数,具体请见下面的流程图:
整个页面的代码如下,其中用到了笔者《JavaScript类库/组件/框架封装的总体结构》一文中提到的框架,封装了一个定时运行器,具体用法见注释:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content ="http://blog.csdn.net/NearEast"/>
<title>check in page</title>
<style type="text/css">
.clear{
clear:both;
}
.float{
float:left;
}
</style>
</head>
<body>
<div id="dInfo" class="float"></div>
<div class="clear"></div>
<div id="wrap">
<iframe class="float" id='i_iframe1' name="n_iframe1" frameborder="0"></iframe>
<iframe class="float" id='i_iframe2' name="n_iframe2" frameborder="0"></iframe>
<form target="n_iframe1" name="loginform" method="post" action="http://192.168.19.11:8010/signin/signin.jsp">
<input name="name" type='hidden' value='nidong' />
<input name="passwd" type='hidden' value='11111111' />
</form>
</div>
</body>
<script type="text/javascript">
//封装一个定时运行器
(function( window, undefined ) {
var doc = window.document;
var _checkTime, _func, _tip, _print;
/**
初始化参数checkTime指定功能执行的时段,默认时间为'8:15'到'9:00',以及'12:35'到'14:00'两个时段
checkTime应该是24小时制的,并且前面的绝对时间小于后面的绝对时间,例如'00:00:10'在'23:59'的前面
func:在该时间段要执行的功能
printFunc:日志信息的打印方法,默认为console.log方法打日志
tip:要执行的功能的描述,tip可以是html语句,与printFunc结合可能达到各种效果,如例子所示
*/
var checkUtil = function(conf) {
_checkTime = conf.checkTime || ['8:15', '9:00', '12:35','14:00'];
_func = conf.func;
_tip = conf.tip || '功能执行';
_print = conf.printFunc || console.log;
_checkAndSet();
};
window.checkUtil= checkUtil;
/**基于一个指定日期的时间base,通过'hh:mm:ss'格式的时间字符串,获取其毫秒时间
默认秒数为0
*/
function _getMillisecond(base, str){
var slices = str.split(':');
if(!base instanceof Date || slices.length<2){
alert('param error');
return;
}
base.setHours(parseInt(slices[0]));
base.setMinutes(parseInt(slices[1]));
base.setSeconds(parseInt(slices[2]||'0'));
return base.getTime();
}
/**计算是否处在签到时间段(flag==true),并返回距离下一次签到还有多久(毫秒)
*/
function _getCheckTime(){
var split = [], d = new Date(), curTime = new Date(d);
d.setMilliseconds(0);
for(var i=0;i<_checkTime.length;i++){
split[i] = _getMillisecond(d, _checkTime[i]);
}
//最后一个元素为第一个元素加上24小时,意为循环到第二天
split.push(24*3600*1000 + split[0]);
split.unshift(_getMillisecond(d, '00:00:00'));
var start, end;
for(var i=0;i<split.length;i++){
start = split[i];
end = split[(i+1)%split.length];
if(start<=curTime && curTime<=end){
return{
eclipse:end - curTime,
flag:i%2==1/*第奇数个元素*/
}
}
}
return 'error';
}
function _addCookie(name, value) {
var hours = 2;
var exp = new Date();
exp.setTime(exp.getTime() + hours * 60 * 60 * 1000);
doc.cookie = name + "=" + escape(value) + ";expires="+ exp.toGMTString();
}
function _getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = doc.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
function _delCookie(name) {
doc.cookie = name + "=n;expires=Thu, 01-Jan-70 00:00:01 GMT";
}
function _checkAndSet(){
var ret = _getCheckTime();
if(ret.flag){
_print('当前为' + _tip + '时段');
var checked = _getCookie('_checked');
if(checked == 'true'){
_print('本时段已' + _tip);
}else{
_print('现在执行' + _tip);
_func();
//print some information
_addCookie('_checked', 'true');
}
}else{
_print('当前非' + _tip + '时段');
_delCookie('_checked');
}
setTimeout(function(){
_checkAndSet();
}, ret.eclipse);
_print('将于' + ret.eclipse/1000 + '秒之后,执行_checkAndSet()');
};
})(window);
window.onresize = function(){
var frm = document.getElementById('i_iframe1');
var frm2 = document.getElementById('i_iframe2');
document.getElementById('wrap').style.height = document.documentElement.clientHeight+'px';
frm.width=frm2.width='50%';//document.documentElement.clientWidth/2;
frm.height=frm2.height='100%';//document.documentElement.clientHeight;
};
window.onload = function(){
window.onresize();
///As a single page
checkUtil({func:function(){
checkon();
}, tip:'<a href="javascript:checkon();">签到</a>'
, checkTime:['15:50', '15:50:10', '15:50:20','15:50:30']
, printFunc:function(txt){
document.getElementById('dInfo').innerHTML += txt+'<br>';
}
});
}
function checkon(){
loginform.childNodes[1].value='nidong';
loginform.target="n_iframe1";
loginform.submit();
loginform.childNodes[1].value='gengap';
loginform.target="n_iframe2";
loginform.submit();
}
</script>
</html>
以上页面的js代码中,封装了一个checkUtil组件,可以用来定期执行任务。初始化参数checkTime中可以给出一天之内的多个时段,只要浏览器页面是打开状态,到了一定时间就将运行func参数指定的函数;如果天天不关机,就可以一劳永逸,不用操心func函数的运行了。不过虽然代码几经修改,存在别的小问题还是难免的,也不能完全依赖它做事;定期查看一下日志还是很必要的。
由于Chrome只支持online cookie,直接把代码粘到一个本地文件运行是无效的,其它浏览器不存在这个问题。