之前一直很想用javascript写一个日历,但是因为完全没有好的思路, 所以迟迟没有尝试。最近在网上刚好看到用javascript编写的简单日历的例子,代码量虽然不大, 但是我觉得很好地阐述了js日历的实现原理。自己也尝试着做了一下,收获蛮大,掌握了基本的实现原理后,再想增加更多的功能,完全就可以自由发挥了,先在这里分享一下吧,有兴趣的可以试试!

一.表格行数问题

既然要显示日期表格的话,首先得知道这个表格有多少行多少列,列数是已经确定的,从星期天(日历上第1列是星期天)到星期六一共7列。要解决行数问题之前,还得先知道这个月的第1天是星期几,因为每个月的1号并不都是从日历上的星期天开始排的,可能1号是星期五,星期六也说不定,所以1号的左边部分,就得用空表格代替了。那么用多少个空表格代替呢,这里就得用到getDay()方法了,该方法返回数组[0-6]中的一个数字,0代表星期天,1代表星期一,2代表星期二,以此类推。所以如果一个月的1号是星期五的话,那么刚好左边需要5个空表格代替。然后,假如一个月有31天,最后求出的表格行数就是:

 var tr_nums = Math.ceil((5 + 31)/7);

当然,并不是每个月都是31天,所以我们得创建一个包含12个月份的数组,每个元素代表每个月份所包含的天数。但是2月份比较特殊,闰年的2月份有29天,平年的2月份只有28天。所以,在创建数组之前,得自己创建一个判断闰年的函数:

 //如果当前年份能被4整除但是不能被100整除或者能被400整除,即可确定为闰年,返回1,否则返回0
function isLeap(year) {
return year % 4 == 0 ? (year % 100 != 0 ? 1 : (year % 400 == 0 ? 1 : 0)) : 0;
}

  

然后我们创建一个月份数组:

 var days_per_month = new Array(31, 28 + isLeap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

这样就能保证无论是平年还是闰年都会取出正确的天数,下面的代码用于获取今天的相关信息:

 var today = new Date(),              //获取当前日期
y = today.getFullYear(), //获取日期中的年份
m = today.getMonth(), //获取日期中的月份(需要注意的是:月份是从0开始计算,获取的值比正常月份的值少1)
d = today.getDate(), //获取日期中的日(方便在建立日期表格时高亮显示当天)
firstday = new Date(y, m, 1), //获取当月的第一天
dayOfWeek = firstday.getDay(), //判断第一天是星期几(返回[0-6]中的一个,0代表星期天,1代表星期一,以此类推)
days_per_month = new Array(31, 28 + isLeap(y), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), //创建月份数组

所以最后就可以获取当月所需表格的行数:

 var str_nums = Math.ceil((dayOfWeek + days_per_month[m]) / 7); //确定日期表格所需的行数

二.打印日历表格

表格本身是一个二维数组,所以让for大师出来跑两个循环就搞定啦,代码如下:

 for (i = 0; i < str_nums; i += 1) {     //第一层for循环创建tr标签
document.write('<tr>');
for (k = 0; k < 7; k++) { //第二层for循环创建td标签
var idx = 7 * i + k; //为每个表格创建索引,从0开始
var date = idx - dayOfWeek + 1; //将当月的1号与星期进行匹配
//do something else
}
document.write('</tr>');
}

三.附上完整的js日历代码

 <script>
//判断当前年份是否是闰年(闰年2月份有29天,平年2月份只有28天)
function isLeap(year) {
return year % 4 == 0 ? (year % 100 != 0 ? 1 : (year % 400 == 0 ? 1 : 0)) : 0;
}
var i, k,
today = new Date(), //获取当前日期
y = today.getFullYear(), //获取日期中的年份
m = today.getMonth(), //获取日期中的月份(需要注意的是:月份是从0开始计算,获取的值比正常月份的值少1)
d = today.getDate(), //获取日期中的日(方便在建立日期表格时高亮显示当天)
firstday = new Date(y, m, 1), //获取当月的第一天
dayOfWeek = firstday.getDay(), //判断第一天是星期几(返回[0-6]中的一个,0代表星期天,1代表星期一,以此类推)
days_per_month = new Array(31, 28 + isLeap(y), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), //创建月份数组
str_nums = Math.ceil((dayOfWeek + days_per_month[m]) / 7); //确定日期表格所需的行数
document.write("<table cellspacing='0'><tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>"); //打印表格第一行(显示星期)
for (i = 0; i < str_nums; i += 1) { //二维数组创建日期表格
document.write('<tr>');
for (k = 0; k < 7; k++) {
var idx = 7 * i + k; //为每个表格创建索引,从0开始
var date = idx - dayOfWeek + 1; //将当月的1号与星期进行匹配
(date <= 0 || date > days_per_month[m]) ? date = '&nbsp;': date = idx - dayOfWeek + 1; //索引小于等于0或者大于月份最大值就用空表格代替
date == d ? document.write('<td class="today">' + date + '</td>') : document.write('<td>' + date + '</td>'); //高亮显示当天
}
document.write('</tr>');
}
document.write('</table>');
</script>

css部分大家就自由发挥吧,当前时间是2016年5月2号,效果图如下:

github地址: https://github.com/Downsview/calendar-demo/

js编写当天简单日历的更多相关文章

  1. JS写一个简单日历

    JS写一个日历,配合jQuery操作DOM <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...

  2. jquery编写的简单日历

    以前在开发web页面的时候遇到日历,都是直接引入一些日历组件来用,一直不太明白实现原理,总感觉挺复杂的. 今天尝试着用jquery写了一个简单的日历功能,可以选择年份,月份,返回今天,原来简单的日历功 ...

  3. 使用js编写一个简单的运动框架

    下班后,,没事捣鼓捣鼓个人的小爱好. 首先,说明我的这个运动框架(css所有属性)也是常见的框架一种,健壮性并不是太好,对于新手学习倒是挺好,,若是大神,老司机请拐弯. 上来,我们先定义一个区块,然后 ...

  4. 利用js编写一个简单的html表单验证,验证通过时提交数据(附源码)

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  5. js 获取当天23点59分59秒 时间戳 (最简单的方法)

    js 获取当天23点59分59秒 时间戳 (最简单的方法) new Date(new Date(new Date().toLocaleDateString()).getTime()+24*60*60* ...

  6. js超简单日历

    用原生js写了一个超级简单的日历.当做是练习js中的Date类型. 思路: 获取某个日期,根据年份计算出每个月的天数. 利用Date中的getDay()知道该月份的第一天为星期几. 循环创建表格,显示 ...

  7. JS编写日历控件(支持单日历 双日历 甚至多日历等)

    前言: 最近几天都在研究日历控件编写,当然前提我要说明下,当然看过别人写的源码 所以脑子一热 就想用自己的编码方式 来写一套可扩展性 可维护性 性能高点的代码控件出来,就算练习练习下,所以前几天晚上下 ...

  8. 为Node.js编写组件的几种方式

    本文主要备忘为Node.js编写组件的三种实现:纯js实现.v8 API实现(同步&异步).借助swig框架实现. 关键字:Node.js.C++.v8.swig.异步.回调. 简介 首先介绍 ...

  9. js编写验证码

    这是一个简单的js编写的验证码,自己已经亲自验证,没有问题了 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...

随机推荐

  1. 利用深搜和宽搜两种算法解决TreeView控件加载文件的问题。

    利用TreeView控件加载文件,必须遍历处所有的文件和文件夹. 深搜算法用到了递归. using System; using System.Collections.Generic; using Sy ...

  2. IOS开发-KVO

    一.什么是kvo? key-value observing,观察者模式 观察者,观察对象属性的变化,当被观察者该属性发生变化时,观察者会接收到通知,可以在回调函数中做相应的处理 二.有什么作用? 变化 ...

  3. javascript学习5

    JavaScript Array(数组)对象 数组对象的作用是:使用单独的变量名来存储一系列的值. 实例 创建数组 创建数组,为其赋值,然后输出这些值. For...In 声明 使用 for...in ...

  4. C#日期格式转换

    DateTime dt = DateTime.Now; // Label1.Text = dt.ToString();//2005-11-5 13:21:25 // Label2.Text = dt. ...

  5. Redis Lua脚本原理

    2.6版本之后支持嵌入Lua脚本,客户端使用Lua脚本,直接在服务器端原子的执行多条命令 Lua脚本执行过程 创建并修改Lua环境 1 创建基础Lua环境 2 载入函数库 3 创建全局表格Lua 4 ...

  6. 解决Fedora解压文件产生乱码的问题

    最近有发现在使用Linux的时候,之前也遇到过在ubuntu下,最后ubuntu貌似在原生下优化了这个问题,现在换到了fedora上的时候问题又出现了,解压出来的文件中文乱码. 为了在linux下可以 ...

  7. 简单的描述Java中的构造函数,及访问修饰符

    作为一个Java 初学者,对Java的理解可能有些片面,甚至有些错误的理解,对于观看此处的您,希望您选择性观看!!! 访问修饰符: 1.常用访问修饰符: public 共有的 private 私有的 ...

  8. STM32 DMA使用详解

    DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧.下面用问答的形式表达我的思路. DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数 ...

  9. Socket开发框架之消息的回调处理

    在一般的Socket应用里面,很多时候数据的发送和接收是分开处理的,也就是我们发送一个消息,不知道这个请求消息什么时候得到应答消息,而且收到对应的应答消息的时候,如果操作界面的内容,也是需要特别处理的 ...

  10. 基于MVC4+EasyUI的Web开发框架经验总结(7)--实现省份、城市、行政区三者联动

    为了提高客户体验和进行一些技术探索,现在正准备把我自己的客户关系管理系统CRM在做一个Web的版本,因此对基于MVC的Web界面继续进行一些研究和优化,力求在功能和界面上保持和Winform一致,本文 ...