如何通过JS实现日历简单算法


Posted in Javascript onOctober 14, 2020

最近有用到日历可需要编辑文本的日历,为了绑定数据的方便,所以用js写了一套日历,其实思想也是很简单。实现步骤如下:

1、首先取得处理月的总天数

js不提供此参数,我们需要计算。考虑到闰年问题会影响二月份的天数,我们先编写一个判断闰年的自编函数:

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

2、接着定义一个包含十二个月在内的月份总天数的数组:

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

3、m_days这个数组里,二月份的天数已经加入闰年的信息:

28+is_leap(ynow) 。数组元素从0开始,正好对应于JS提供的Date函数提供的getMonth返回值,即0表示一月,1表示二月,2表示三月,依此类推。

这样,各月总数可以这样取得:m_days[x]。其中,x为0至11的自然数。

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

可以使用Date函数的getDay取得,返回的值从0到6,0表示星期一,1表示星期二,2表示星期三,其余依此类推。代码如下(假设要处理的时间为2008年3月):

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

有了月总天数和该月第一天是星期几这两个已知条件,就可以解决表格所需行数问题:(当前月天数+第一天是星期几的数值)除以七。表格函数需要整数,因此,我们使用Math.ceil来处理:

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

表格中的tr标签实际上代表表格的行,因此变量tr_str是我们往下写表格的重要依据。

5、打印日历表格

可以使用两个for语句嵌套起来实现:外层for语句写行,内层for语句写单元格。

for(i=0;i<tr_str;i++) { //表格的行
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=" " : date_str=idx-firstday+1; //过滤无效日期(小于等于零的、大于月总天数的)


$(".date-info .date").last().append("<td>" + date_str + "</td>");

}
}

单元格的自然序号是否代表有效日期非常关键,为此必须加入一个过滤机制:仅打印有效的日期。有效的日期大于0小于小于等于处理月的总天数。

6、上一个月与下一个月

if(mnow<=0){
mnow=11;

ynow=ynow-1;
}else{

mnow--;
}
 
if(mnow>=11){

mnow=0;

ynow=ynow+1;
}else{

mnow++;
}

获取上一个月时,到1月份需注意;获取下一个月时,到12月份时要注意。

渲染时,需要先移除旧的日历,再添加新的日历。

var nstr = new Date();
var ynow = nstr.getFullYear();
var mnow = nstr.getMonth();
var dnow = nstr.getDate();
var mnow_real = mnow;
calendar(nstr,ynow,mnow,dnow);
monDetail(ynow,mnow_real);
 
function monDetail(ynow,mnow){
 mnow_real = mnow+1;
 $(".month-detail").html(ynow+"-"+ mnow_real); //显示当前年月
}
 
function is_leap(year) { //判断是否为闰年
 return (year%100==0?res=(year%400==0?1:0):res=(year%4==0?1:0));
}
 
function preMonth(){ //上一个月
 console.log(mnow);
 if(mnow<=0){
 mnow=11;
 ynow=ynow-1;
 }else{
 mnow--;
 }
 calendar(nstr,ynow,mnow,dnow);
 monDetail(ynow,mnow);
}
 
function nextMonth(){ //下一个月
 
 if(mnow>=11){
 mnow=0;
 ynow=ynow+1;
 }else{
 mnow++;
 }
 calendar(nstr,ynow,mnow,dnow);
 monDetail(ynow,mnow);
 
}
 
function calendar(nstr,ynow,mnow,dnow){
 $(".date-info tr.date").remove(); /改变月份时,先移除旧的日期
 var nlstr = new Date(ynow,mnow,1); //当月第一天
 var firstday = nlstr.getDay(); //第一天星期几
 
 var m_days=new Array(31,28+is_leap(ynow),31,30,31,31,30,31,30,31,30,31); //每个月的天数
 
 var tr_str=Math.ceil((m_days[mnow] + firstday)/7); //当前月天数+第一天是星期几的数值 获得 表格行数
 var i,k,idx,date_str;
 for(i=0;i<tr_str;i++) { //表格的行
 $(".date-info tbody").append("<tr></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=" " : date_str=idx-firstday+1; //过滤无效日期(小于等于零的、大于月总天数的)
 $(".date-info .date").last().append("<td>" + date_str + "</td>");
 }
 
 }
}

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

Javascript 相关文章推荐
createElement动态创建HTML对象脚本代码
Nov 24 Javascript
基于Jquery实现仿百度百科右侧导航代码附源码下载
Nov 27 Javascript
基于Vuejs实现购物车功能
Aug 02 Javascript
jquery ajaxfileupload异步上传插件使用详解
Feb 08 Javascript
Vue2.0利用 v-model 实现组件props双向绑定的优美解决方案
Mar 13 Javascript
认识less和webstrom的less配置方法
Aug 02 Javascript
基于Vue实现拖拽功能
Jul 29 Javascript
Vue引入sass并配置全局变量的方法
Jun 27 Javascript
重新认识vue之事件阻止冒泡的实现
Aug 02 Javascript
jsonp实现百度下拉框功能的方法分析
May 10 Javascript
浅谈Webpack4 Tree Shaking 终极优化指南
Nov 18 Javascript
浅析JS中NEW的实现原理及重写
Feb 20 Javascript
浅谈js数组splice删除某个元素爬坑
Oct 14 #Javascript
如何使用JS console.log()技巧提高工作效率
Oct 14 #Javascript
JavaScript Blob对象原理及用法详解
Oct 14 #Javascript
基于javascript原生判断DOM是否加载完毕
Oct 14 #Javascript
JavaScript常用进制转换及位运算实例解析
Oct 14 #Javascript
Vue实现鼠标经过文字显示悬浮框效果的示例代码
Oct 14 #Javascript
JavaScript本地储存:localStorage、sessionStorage、cookie的使用
Oct 13 #Javascript
You might like
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
2014/05/08 PHP
解决cPanel无法安装php5.2.17
2014/06/22 PHP
如何利用http协议发布博客园博文评论
2015/08/03 PHP
PHP的垃圾回收机制代码实例讲解
2021/02/27 PHP
不错的新闻标题颜色效果
2006/12/10 Javascript
JavaScript 应用类库代码
2008/06/02 Javascript
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
jQuery EasyUI API 中文文档 - Dialog对话框
2011/11/15 Javascript
javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图
2013/01/09 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
2013/04/02 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
详解Angular的数据显示优化处理
2016/12/26 Javascript
JavaScript在控件上添加倒计时功能的实现代码
2017/07/04 Javascript
js实现动态改变radio状态的方法
2018/02/28 Javascript
微信小程序时间轴实现方法示例
2019/01/14 Javascript
深入理解Puppeteer的入门教程和实践
2019/03/05 Javascript
Laravel admin实现消息提醒、播放音频功能
2019/07/10 Javascript
Vue前端项目部署IIS的实现
2020/01/06 Javascript
vue-socket.io接收不到数据问题的解决方法
2020/05/13 Javascript
原生JS实现九宫格抽奖
2020/09/13 Javascript
[04:29]2014DOTA2国际邀请赛 主赛事第三日TOPPLAY
2014/07/21 DOTA
[00:20]TI9观赛名额抽取Ⅱ
2019/07/24 DOTA
Python内置函数Type()函数一个有趣的用法
2015/02/18 Python
Android应用开发中Action bar编写的入门教程
2016/02/26 Python
python2.6.6如何升级到python2.7.14
2018/04/08 Python
Python List cmp()知识点总结
2019/02/18 Python
使用Python Pandas处理亿级数据的方法
2019/06/24 Python
python 装饰器重要在哪
2021/02/14 Python
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
汽车专业学生自我评价
2014/01/19 职场文书
运动会通讯稿300字
2014/02/02 职场文书
食品安全汇报材料
2014/08/18 职场文书
2014年学校禁毒工作总结
2014/12/23 职场文书
签订劳动合同通知书
2015/04/16 职场文书
关于SpringBoot 使用 Redis 分布式锁解决并发问题
2021/11/17 Redis