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 相关文章推荐
javascript 二进制运算技巧解析
Nov 27 Javascript
jQuery中click事件用法实例
Dec 26 Javascript
jQuery中:eq()选择器用法实例
Dec 29 Javascript
Bootstrap表单Form全面解析
Jun 13 Javascript
Angular2 环境配置详细介绍
Sep 21 Javascript
js拖拽功能实现代码解析
Nov 28 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
Sep 11 Javascript
vue中element组件样式修改无效的解决方法
Feb 03 Javascript
javascript获取select值的方法完整实例
Jun 20 Javascript
详解React路由传参方法汇总记录
Nov 29 Javascript
javascript canvas实现雨滴效果
Jun 09 Javascript
JavaScript流程控制(循环)
Dec 06 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
phpfans留言版用到的数据操作类和分页类
2007/01/04 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
2019/12/18 PHP
原型方法的不同写法居然会影响调试的解决方法
2007/03/08 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
2014/09/23 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
js控制文本框只输入数字和小数点的方法
2015/03/10 Javascript
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
jQuery居中元素scrollleft计算方法示例
2017/01/16 Javascript
关于vue中 $emit的用法详解
2018/04/12 Javascript
Angular 数据请求的实现方法
2018/05/07 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
2018/08/08 jQuery
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
微信小程序实现的动态设置导航栏标题功能示例
2019/01/31 Javascript
微信小程序分享小程序码的生成(带参数)以及参数的获取
2020/03/25 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
用Javascript实现发送短信验证码间隔功能
2021/02/08 Javascript
Python实现控制台进度条功能
2016/01/04 Python
Django框架多表查询实例分析
2018/07/04 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
详解Python sys.argv使用方法
2019/05/10 Python
python标记语句块使用方法总结
2019/08/05 Python
Django 限制访问频率的思路详解
2019/12/24 Python
python能在浏览器能运行吗
2020/06/17 Python
html5 canvas的绘制文本自动换行的示例代码
2018/09/17 HTML / CSS
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
Nike俄罗斯官方网站:Nike RU
2021/03/05 全球购物
最新的大学生找工作自我评价
2013/09/29 职场文书
现金会计岗位职责
2013/12/05 职场文书
综合内勤岗位职责
2014/04/14 职场文书
优秀团干部个人事迹
2014/05/29 职场文书
基层党员对照检查材料
2014/09/24 职场文书
2014年党建工作总结
2014/11/11 职场文书
2015年人事专员工作总结
2015/04/29 职场文书
Django实现WebSocket在线聊天室功能(channels库)
2021/09/25 Python
MySQL数据库 任意ip连接方法
2022/05/20 MySQL