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 相关文章推荐
UI Events 用户界面事件
Jun 27 Javascript
关于js中alert弹出窗口文本换行问题简单详细说明
Dec 11 Javascript
javascript的parseFloat()方法精度问题探讨
Nov 26 Javascript
jQuery实现垂直半透明手风琴特效代码分享
Aug 21 Javascript
让你一句话理解闭包(简单易懂)
Jun 03 Javascript
JS数组返回去重后数据的方法解析
Jan 03 Javascript
IntersectionObserver实现图片懒加载的示例
Sep 29 Javascript
Vue filter介绍及其使用详解
Oct 21 Javascript
详解Vue Elementui中的Tag与页面其它元素相互交互的两三事
Sep 25 Javascript
简谈创建React Component的几种方式
Jun 15 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
Feb 15 Javascript
js+h5 canvas实现图片验证码
Oct 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
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
php查询ip所在地的方法
2014/12/05 PHP
php针对cookie操作的队列操作类实例
2014/12/10 PHP
php将html转成wml的WAP标记语言实例
2015/07/08 PHP
CI框架实现cookie登陆的方法详解
2016/05/18 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
Web前端设计模式  制作漂亮的弹出层
2010/10/29 Javascript
jQuery $.get 的妙用 访问本地文本文件
2012/07/12 Javascript
easyui datagrid 键盘上下控制选中行示例
2014/03/31 Javascript
js全选按钮的实现方法
2015/11/17 Javascript
全面详细的jQuery常见开发技巧手册
2016/02/21 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
jQuery EasyUI 折叠面板accordion的使用实例(分享)
2017/12/25 jQuery
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
JS与SQL方式随机生成高强度密码示例
2018/12/29 Javascript
js验证身份证号码记录的方法
2019/04/26 Javascript
ES6模板字符串和标签模板的应用实例分析
2019/06/25 Javascript
深入理解javascript prototype的相关知识
2019/09/19 Javascript
vue组件系列之TagsInput详解
2020/05/14 Javascript
Python中pygal绘制雷达图代码分享
2017/12/07 Python
Python利用字典将两个通讯录文本合并为一个文本实例
2018/01/16 Python
python字符串和常用数据结构知识总结
2019/05/21 Python
python使用PIL剪切和拼接图片
2020/03/23 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
Python如何输出警告信息
2020/07/30 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
美国汽车零部件和配件网站:CarParts
2019/03/13 全球购物
中文系学生自荐信范文
2013/11/13 职场文书
食品销售计划书
2014/04/26 职场文书
董事长岗位职责
2015/02/13 职场文书
2015年教师教学工作总结
2015/04/28 职场文书
运动会通讯稿600字
2015/07/20 职场文书
军训决心书范文
2015/09/22 职场文书
2016年公共机构节能宣传周活动总结
2016/04/05 职场文书
MySql数据库触发器使用教程
2022/06/01 MySQL