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 相关文章推荐
jQuery表格行换色的三种实现方法
Jun 27 Javascript
jquer之ajaxQueue简单实现代码
Sep 15 Javascript
JavaScript设置IFrame高度自适应(兼容各主流浏览器)
Jun 05 Javascript
jQuery实现MSN中文网滑动Tab菜单效果代码
Sep 09 Javascript
使用jQuery获取data-的自定义属性
Nov 10 Javascript
浅析jquery如何判断滚动条滚到页面底部并执行事件
Apr 29 Javascript
AngularJS过滤器filter用法实例分析
Nov 04 Javascript
js仿iphone秒表功能 计算平均数
Jan 11 Javascript
Angular.JS中的this指向详解
May 17 Javascript
微信小程序实现tab左右切换效果
Nov 15 Javascript
vue文件运行的方法教学
Feb 12 Javascript
javascript实现简易数码时钟
Mar 30 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面向对象——访问修饰符介绍
2012/11/08 PHP
PHP关于IE下的iframe跨域导致session丢失问题解决方法
2013/10/10 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
记录一次排查PHP脚本执行卡住的问题
2016/12/27 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
CI框架附属类用法分析
2018/12/26 PHP
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
javascript窗口宽高,鼠标位置,滚动高度(详细解析)
2013/11/18 Javascript
javascript去除字符串左右两端的空格
2015/02/05 Javascript
利用JavaScript脚本实现滚屏效果的方法
2015/07/07 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
js如何实现淡入淡出效果
2020/11/18 Javascript
返回函数的JavaScript函数
2016/06/14 Javascript
AngularJS 指令的交互详解及实例代码
2016/09/14 Javascript
一个小时快速搭建微信小程序的方法步骤
2019/04/15 Javascript
angularjs请求数据的方法示例
2019/08/06 Javascript
javascript实现页面的实时时钟显示示例
2020/08/06 Javascript
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
用Python编写一个简单的Lisp解释器的教程
2015/04/03 Python
Python 爬虫模拟登陆知乎
2016/09/23 Python
python对json的相关操作实例详解
2017/01/04 Python
Python 查看文件的读写权限方法
2018/01/23 Python
python频繁写入文件时提速的方法
2019/06/26 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
Python request post上传文件常见要点
2020/11/20 Python
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
小学家长会邀请函
2014/01/23 职场文书
竞选班委演讲稿
2014/04/28 职场文书
中学教师师德师风演讲稿
2014/08/22 职场文书
2014年重阳节老干部座谈会上的讲话稿
2014/09/25 职场文书
2014年司法所工作总结
2014/11/22 职场文书
干货:如何写好观后感 !
2019/05/21 职场文书
MySQL infobright的安装步骤
2021/04/07 MySQL
HTML基础详解(下)
2021/10/16 HTML / CSS