JavaScript实现每日签到与动态日历生成

作者:拾光时间:2026-10-22 19:22:43浏览:445

本文详细解析如何使用JavaScript实现每日签到功能及动态生成当月日历表。通过封装工具类处理闰年判断、月份天数计算及表格行列布局,结合后台返回的已签到数据集合,实现签到状态的动态渲染。代码兼容PC与移动端浏览器,提供完整的HTML结构与JS逻辑参考。

JavaScript实现每日签到与动态日历生成

本文分享了一段使用JavaScript实现每日签到功能的具体代码示例,供开发者参考与学习。

JavaScript实现每日签到与动态日历生成

前端JavaScript逻辑部分:

前端JavaScript逻辑部分


var calUtil = { 
 getDaysInmonth : function(iMonth, iYear){ //当前年月的总天数 
  var dPrevDate = new Date(iYear, iMonth, 0); 
  return dPrevDate.getDate(); 
 }, 
 bulidCal : function(iYear, iMonth) { //构建当前年月对应的日历
  var aMonth = new Array(); 
  aMonth[0] = new Array(7); 
  aMonth[1] = new Array(7); 
  aMonth[2] = new Array(7); 
  aMonth[3] = new Array(7); 
  aMonth[4] = new Array(7); 
  aMonth[5] = new Array(7); 
  aMonth[6] = new Array(7); 
  var dCalDate = new Date(iYear, iMonth - 1, 1); 
  var iDayOfFirst = dCalDate.getDay(); 
  var iDaysInMonth = calUtil.getDaysInmonth(iMonth, iYear); 
  var iVarDate = 1; 
  var d, w; 
  aMonth[0][0] = "日"; 
  aMonth[0][1] = "一"; 
  aMonth[0][2] = "二"; 
  aMonth[0][3] = "三"; 
  aMonth[0][4] = "四"; 
  aMonth[0][5] = "五"; 
  aMonth[0][6] = "六"; 
  for (d = iDayOfFirst; d < 7; d++) { 
  aMonth[1][d] = iVarDate; 
  iVarDate++; 
  } 
  for (w = 2; w < 7; w++) { 
  for (d = 0; d < 7; d++) { 
   if (iVarDate <= iDaysInMonth) { 
   aMonth[w][d] = iVarDate; 
   iVarDate++; 
   } 
  } 
  } 
  return aMonth; 
 }, 
 ifHasSigned : function(signList,day){ 
  var signed = false; 
  $.each(signList,function(index,item){ 
   var date = new Date(item.signDate); 
   if(date.getDate() == day) { 
    signed = true; 
    return false; 
   } 
  }); 
  return signed ; 
 }, 
 drawCal : function(iYear, iMonth ,signList) { 
  var currentYearMonth = iYear+"年"+iMonth+"月"; 
  var myMonth = calUtil.bulidCal(iYear, iMonth); 
  var htmls = new Array(); 
  htmls.push("<div class='sign_main' id='sign_layer'>"); 
  htmls.push("<div class='sign_succ_calendar_title'>"); 
  htmls.push("<div class='calendar_month_span'>"+currentYearMonth+"</div>"); 
  htmls.push("</div>"); 
  htmls.push("<div class='sign' id='sign_cal'>"); 
  htmls.push("<table class='table'>"); 
  htmls.push("<tr>"); 
  htmls.push("<th>" + myMonth[0][0] + "</th>"); 
  htmls.push("<th>" + myMonth[0][1] + "</th>"); 
  htmls.push("<th>" + myMonth[0][2] + "</th>"); 
  htmls.push("<th>" + myMonth[0][3] + "</th>"); 
  htmls.push("<th>" + myMonth[0][4] + "</th>"); 
  htmls.push("<th>" + myMonth[0][5] + "</th>"); 
  htmls.push("<th>" + myMonth[0][6] + "</th>"); 
  htmls.push("</tr>"); 
  var d, w; 
  for (w = 1; w < 7; w++) { 
  htmls.push("<tr>"); 
  for (d = 0; d < 7; d++) { 
   var ifHasSigned = calUtil.ifHasSigned(signList,myMonth[w][d]); 
   if(ifHasSigned){ 
   htmls.push("<td class='on'>" + (!isNaN(myMonth[w][d]) ? myMonth[w][d] : " ") + "</td>"); 
   } else { 
   htmls.push("<td>" + (!isNaN(myMonth[w][d]) ? myMonth[w][d] : " ") + "</td>"); 
   } 
  } 
  htmls.push("</tr>"); 
  } 
  htmls.push("</table>"); 
  htmls.push("</div>"); 
  htmls.push("</div>"); 
  return htmls.join(''); 
 } 
}; 

页面HTML结构与样式代码:

 

页面HTML结构与样式代码


<style type="text/css"> 
@media screen and (min-width:1024px) { 
 .rich_media { 
  width: 500px; 
  margin-left: auto; 
  margin-right: auto; 
  padding: 20px; 
 } 
} 
</style> 
</head> 
<body style="background-color: #fff;"> 
 <div class="rich_media"> 
   <div id="page-content"> 
    <div style="text-align: center;background-color: #2FAA00;height: 50px;margin-bottom: 20px;"> 
     <span style="cursor: pointer;font-weight: 600;font-size: 20px;color: #fff;height: 50px;line-height: 50px;">每日签到</span> 
     <input type="hidden" id="userId" value="${user.id }" /> 
    </div> 
    <div class="container-fluid"> 
     <div class="row-fluid" id="calendar"> 

     </div> 
     <div id="btnDiv" style="display: none;"> 
      <div class="row-fluid text-center"> 
       <span id="sing_for_number" class="btn btn-default">签到</span> 
      </div> 
     </div> 
    </div> 
   </div> 
 </div> 
</body> 

JavaScript调用方法:

JavaScript调用方法


var str = calUtil.drawCal(current.getFullYear(),current.getMonth() + 1,signList); 
$("#calendar").html(str); 

签到数据交互说明

说明:signList变量用于接收后台查询返回的已签到时间集合。该集合传入JS方法后,程序会遍历判断哪些日期已完成签到,并据此改变对应日期的显示效果,具体表现如上图所示。此签到页面设计兼容手机浏览器,具备良好的响应式适配能力。

核心逻辑提要:

核心逻辑提要

本文以生成当前时间环境下当月的日历表为例,采用最简化的方法实现JavaScript日历功能,旨在展示JavaScript在实际开发中实用为本、简单为上的解决思路。

Web页面中的日历组件通常依赖表格来装载指定月份的日期信息。因此,编写JS日历的核心在于解决表格的行与列布局问题。列数固定为7列,对应一周七天;行数则需动态计算,因为每月第一天的星期几不固定,导致表格起始位置不同,且各月总天数差异也会影响表格所需的总行数。

一、表格行数的动态计算

1. 获取处理月份的总天数

JavaScript标准库未直接提供月份总天数的参数,需自行计算。由于闰年会影响二月天数,首先编写一个判断闰年的自定义函数:

获取处理月份的总天数


function is_leap(year) {
 return (year%100==0?res=(year%400==0?1:0):res=(year%4==0?1:0));
}

接着定义一个包含十二个月总天数的数组:


m_days=new Array(31,28+is_leap(ynow),31,30,31,31,30,31,30,31,30,31);

在m_days数组中,二月天数已整合闰年判断逻辑:28 + is_leap(ynow)。数组索引从0开始,恰好对应JavaScript Date对象getMonth()方法的返回值(0代表一月,1代表二月,依此类推)。

通过m_days[x]即可获取各月总天数,其中x为0至11的自然数。

2. 计算处理月份第一天是星期几

利用Date对象的getDay()方法获取,返回值范围0至6,其中0代表星期一,1代表星期二,以此类推。示例代码如下(假设处理时间为2008年3月):

计算处理月份第一天是星期几


n1str=new Date(2008,3,1);
firstday=n1str.getDay();

已知月总天数和该月第一天是星期几后,即可计算表格所需行数:(当前月天数 + 第一天是星期几的数值) 除以7。由于表格行数需为整数,使用Math.ceil()函数进行向上取整处理:


tr_str=Math.ceil((m_days[mnow] + firstday)/7);

表格中的tr标签代表行,因此变量tr_str是构建表格行结构的关键依据。

二、打印日历表格

通过两层for循环嵌套实现:外层循环负责生成表格行(tr),内层循环负责生成单元格(td)。

打印日历表格


for(i=0;i<tr_str;i++) { //外层for语句 - tr标签
 document.write("<tr>");
 for(k=0;k<7;k++) { //内层for语句 - td标签
  idx=i*7+k; //表格单元的自然序号
  date_str=idx-firstday+1; //计算日期
  //这里是处理有效日期代码
 } //内层for语句结束
 document.write("</tr>");
} //外层for语句结束

单元格的自然序号是否代表有效日期至关重要,因此需加入过滤机制:仅当日期大于0且小于等于处理月的总天数时,才打印有效日期。

三、完整的JavaScript日历代码示例:

完整的JavaScript日历代码示例


function is_leap(year) { 
 return (year%100==0?res=(year%400==0?1:0):res=(year%4==0?1:0));
} //是否为闰年

var nstr=new Date(); //当前Date资讯
var ynow=nstr.getFullYear(); //年份
var mnow=nstr.getMonth(); //月份
var dnow=nstr.getDate(); //今日日期
var n1str=new Date(ynow,mnow,1); //当月第一天Date资讯

var firstday=n1str.getDay(); //当月第一天星期几

var m_days=new Array(31,28+is_leap(ynow),31,30,31,30,31,31,30,31,30,31); //各月份的总天数

var tr_str=Math.ceil((m_days[mnow] + firstday)/7); //表格所需要行数

//打印表格第一行(有星期标志)
document.write ("<table border='1' align='center' width='220' cellspacing='0'><tr><td align='center'>日</td><td align='center'>一</td><td align='center'>二</td><td align='center'>三</td><td align='center'>四</td><td align='center'>五</td><td align='center'>六</td></tr>");

for(i=0;i<tr_str;i++) { //表格的行
 document.write("<tr>");
 for(k=0;k<7;k++) { //表格每行的单元格
  idx=i*7+k; //单元格自然序列号
  date_str=idx-firstday+1; //计算日期
  (date_str<=0 || date_str>m_days[mnow]) ? date_str="&nbsp;" : date_str=idx-firstday+1; //过滤无效日期(小于等于零的、大于月总天数的)
  //打印日期:今天底色为红
  date_str==dnow ? document.write ("<td align='center' bgcolor='red'>" + date_str + "</td>") : document.write ("<td align='center'>" + date_str + "</td>");
 }
 document.write("</tr>"); //表格的行结束
}

document.write("</table>"); //表格结束

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章