如何通过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 相关文章推荐
IE6-IE9不支持table.innerHTML的解决方法分享
Sep 14 Javascript
JavaScript建立一个语法高亮输入框实现思路
Feb 26 Javascript
Javascript基础教程之break和continue语句
Jan 18 Javascript
AngularJS iframe跨域打开内容时报错误的解决办法
Jan 26 Javascript
js选择器全面解析
Jun 27 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
Nov 17 Javascript
iframe高度自适应及隐藏滚动条的实例详解
Sep 29 Javascript
JavaScript使用类似break机制中断forEach循环的方法
Nov 13 Javascript
js获取 gif 的帧数的代码实例
Sep 10 Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 Javascript
解决vue动态下拉菜单 有数据未反应的问题
Aug 06 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
Aug 07 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 正则判断中文UTF-8或GBK的思路及具体实现
2013/11/26 PHP
迁移PHP版本到PHP7
2015/02/06 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
2017/06/13 PHP
基于prototype扩展的JavaScript常用函数库
2010/11/30 Javascript
把jquery 的dialog和ztree结合实现步骤
2013/08/02 Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
2014/11/19 Javascript
JavaScript中实现依赖注入的思路分享
2015/01/15 Javascript
jquery中radio checked问题
2015/03/16 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
2015/09/19 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
vue.js+boostrap项目实践(案例详解)
2016/09/21 Javascript
jQuery 插件实现随机自由弹跳气泡样式
2017/01/12 Javascript
Vue中添加手机验证码组件功能操作方法
2017/12/07 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
vue实现动态列表点击各行换色的方法
2018/09/13 Javascript
Node.js动手撸一个静态资源服务器的方法
2019/03/09 Javascript
详解vue 路由跳转四种方式 (带参数)
2019/04/28 Javascript
微信小程序实现订单倒计时
2020/11/01 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
layui表格设计以及数据初始化详解
2019/10/26 Javascript
JavaScript中数组去重的5种方法
2020/07/04 Javascript
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
[02:16]深扒TI7聊天轮盘语音出处2
2017/05/11 DOTA
使用python对文件中的数值进行累加的实例
2018/11/28 Python
解决python DataFrame 打印结果不换行问题
2020/04/09 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
举例详解CSS3中的Transition
2015/07/15 HTML / CSS
智能旅行箱:Horizn Studios
2018/04/30 全球购物
销售主管的自我评价分享
2014/01/03 职场文书
教师师德承诺书
2014/03/26 职场文书
合同意向书范本
2014/07/30 职场文书
树转促学习心得体会
2014/09/10 职场文书
2015年七一建党节慰问信
2015/03/23 职场文书
七年级思品教学反思
2016/02/20 职场文书
Java中使用Filter过滤器的方法
2021/06/28 Java/Android
阿里云 Windows server 2019 配置FTP
2022/04/28 Servers