js实现日历的简单算法


Posted in Javascript onJanuary 24, 2017

最近有用到日历可需要编辑文本的日历,为了绑定数据的方便,所以用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 class='day'>" + 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 class='date'></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 class='day'>" + date_str + "</td>");
 }
 
 }
}

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

Javascript 相关文章推荐
js AspxButton的客户端操作
Jun 26 Javascript
js中格式化日期时间型数据函数代码
Nov 08 Javascript
特殊情况下如何获取span里面的值
May 20 Javascript
JavaScript实现的一个倒计时的类
Mar 12 Javascript
JavaScript中用toString()方法返回时间为字符串
Jun 12 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
May 10 Javascript
easyui window refresh 刷新两次的解决方法(推荐)
May 18 Javascript
jQuery实现的放大镜效果示例
Sep 13 Javascript
AngularJS中过滤器的使用与自定义实例代码
Sep 17 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
Jan 20 Javascript
vue实现数字动态翻牌的效果(开箱即用)
Dec 08 Javascript
vue+axios 拦截器实现统一token的案例
Sep 11 Javascript
JSON键值对序列化和反序列化解析
Jan 24 #Javascript
js自制图片放大镜功能
Jan 24 #Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
Jan 24 #Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
Jan 24 #Javascript
JavaScript解析JSON格式数据的方法示例
Jan 24 #Javascript
解决ajax不能访问本地文件问题(利用js跨域原理)
Jan 24 #Javascript
Jquery树插件zTree实现菜单树
Jan 24 #Javascript
You might like
PHP用FTP类上传文件视频等的简单实现方法
2016/09/23 PHP
[原创]后缀就扩展名为js的文件是什么文件
2007/12/06 Javascript
Fastest way to build an HTML string(拼装html字符串的最快方法)
2011/08/20 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
Javascript 数组排序详解
2014/10/22 Javascript
JavaScript获取页面上被选中文字的方法技巧
2015/03/13 Javascript
JavaScript中判断函数、变量是否存在
2015/06/10 Javascript
JavaScript中var关键字的使用详解
2015/08/14 Javascript
javascript实现的网站访问量统计代码
2015/12/20 Javascript
分享10个优化代码的CSS和JavaScript工具
2016/05/11 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
2016/07/01 Javascript
bootstrap学习使用(导航条、下拉菜单、轮播、栅格布局等)
2016/12/01 Javascript
JavaScript获取中英文混合字符串长度的方法示例
2017/02/04 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
vue项目常用组件和框架结构介绍
2017/12/24 Javascript
使用JavaScript实现node.js中的path.join方法
2018/08/12 Javascript
element-ui多文件上传的实现示例
2019/04/10 Javascript
JavaScript单线程和任务队列原理解析
2020/02/04 Javascript
[01:09:50]VP vs Pain 2018国际邀请赛小组赛BO2 第二场
2018/08/20 DOTA
[41:05]Serenity vs Pain 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
python 求1-100之间的奇数或者偶数之和的实例
2019/06/11 Python
python+openCV调用摄像头拍摄和处理图片的实现
2019/08/06 Python
Python paramiko模块使用解析(实现ssh)
2019/08/30 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
分享CSS3制作卡片式图片的方法
2016/07/08 HTML / CSS
eBay德国站:eBay.de
2017/09/14 全球购物
网络工程师个人的自我评价范文
2013/10/01 职场文书
应届生人事助理求职信
2013/11/09 职场文书
大学学生会竞选演讲稿
2014/04/25 职场文书
警示教育活动总结
2014/05/05 职场文书
安全环保标语
2014/06/09 职场文书
远程培训的心得体会
2014/09/01 职场文书
2014年小学国庆节活动方案
2014/09/16 职场文书
在前女友婚礼上,用Python破解了现场的WIFI还把名称改成了
2021/05/28 Python