有这样一个普通的日历需求

第一反应就是找插件,结果找到了,但是改起来非常麻烦,然后查下实现的原理,发现原来很简单,于是自己实现了一个。

首先分析一下这个组件,每页显示的是

当前月的所有日期及所占据的行剩下的格子所属的上一个月的最后几天或下一个月的前几天。

然后,神奇的Date类型原来可以这样获取日期实例:

new Date(2018,4,0)  // 2018年5月第一天的Date实例
new Date(2018,4,0) // 2018年4月最后一天的Date实例
new Date(2018,4,-1) // 2018年4月倒数第二天的Date实例
new Date(2018,4,32) // 2018年6月第一天的Date实例

所以,可以这样获取每一页的第一格的日期:

var monthFirstDate = new Date(2018, 4-1, 1) // 假设现在是四月
var monthFirstDay = monthFirstDate.getDay() // 本月第一天是星期几,星期日是0,星期一是1... // 所以如果每行第一个是星期日,则每一页的第一格的日期:
var pageFirstDate = new Date(2018, 4-1, 1-monthFirstDay)

而本页的下个月的日期的规律是

下个月第一个星期天之前的日期

所以,可以这样获取一页日历所有日期的Date实例

     /**
* @function getCalendarData
* @param {type} opts {
* day: 所在月的某一天的Date实例
* }
* @return {type} {当页所有日期的Date实例(数组)}
*/
function getCalendarData (opts) {
var opt = opts || {}
var _day = opt.day || new Date(), // Date实例,不传取今天
nowMonth = _day.getMonth(),
nowYear = _day.getFullYear(),
nowDate = _day.getDate() var firstDate = new Date(nowYear, nowMonth, 1), // 本月第一天
firstDay = firstDate.getDay(), // 本月第一天是星期几
activeNum = 1
var result = []
// 例: new Date(2018, 4, 0)结果是2018年3月31日,new Date(2018, 4, -1)结果是2018年3月30日
while (!(isNextMonth(_day, new Date(nowYear, nowMonth, activeNum - firstDay)) &&
new Date(nowYear, nowMonth, activeNum - firstDay).getDay() === 0)) {
// 非(当天是下个月的日期&&当天是周日),则推入数组
// 从new Date(nowYear, nowMonth, 1 - firstDay)开始是为了填上日历当前页里的上一个月的日期
result.push(new Date(nowYear, nowMonth, activeNum - firstDay))
activeNum++
}
function isNextMonth (a, b) { // a,b为Date实例
return (b.getFullYear() === a.getFullYear() && b.getMonth() === a.getMonth() + 1) || // 两个月在同一年
(b.getFullYear() === a.getFullYear() + 1 && b.getMonth() === 0 && a.getMonth() === 11) // 不在同一年
} return result
}

再之后,不管你用拼接html字符串还是用vue/react...,把上面的得出的Date实例数组循环一下,生成DOM,加上css,渲染出你想要的日历!

js实现日历的更多相关文章

  1. [JS,Canvas]日历时钟

    [JS,Canvas]日历时钟 Html: <!doctype html> <html> <head> <meta charset="UTF-8&q ...

  2. js简易日历

    js简易日历中设计的知识点:选项卡切换   数组    innerHTML  连接符 与选项卡的区别:div的个数不同 连接符中需要注意的:(优先级) "abc"+12+3+&qu ...

  3. JS输出日历

    页面HTML代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> &l ...

  4. 2.23 js处理日历控件(修改readonly属性)

    2.23 js处理日历控件(修改readonly属性) 前言    日历控件是web网站上经常会遇到的一个场景,有些输入框是可以直接输入日期的,有些不能,以我们经常抢票的12306网站为例,详细讲解如 ...

  5. 使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间。

    使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间. 效果图: 哎,今天就又这么过去了,过的可真快 . 代码如下,复制即可使用: <!DOCTYPE html> & ...

  6. 用JS编写日历的简单思路

    提要:本文以写当前时间环境下当月的日历表为例,用最简单的方法实现JavaScript日历,旨在展示JS世界中实用为本.简单为上的解决问题的思路. Web页中的日历一般离不开表格,通常都使用表格装载指定 ...

  7. js中日历的代码

    Html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  8. JS实现日历控件选择后自动填充

    最近在做人事档案的项目,在做项目的初期对B/S这块不是很熟悉,感觉信心不是很强,随着和师哥同组人员的交流后发现,调试程序越来越好了,现在信心是倍增,只要自己自己踏实的去研究.理解代码慢慢的效果就出来了 ...

  9. 创建一个js日历(原生JS实现日历)

    前言 方法是有参考网上一些资料的,比如闰年的判断,比如每个月第一天是星期几的判断.不说太多,拆分出一个个函数,希望能描述尽可能的清晰明了. 一,判断闰年 //判断闰年 function runNian ...

  10. js 简单日历

    源地址:https://jingyan.baidu.com/article/546ae185fa4f721149f28cbf.htm 文件:index.htm <!DOCTYPE html> ...

随机推荐

  1. Angularjs 跨域post数据到springmvc

    先贴网上己有解决方案链接: http://www.tuicool.com/articles/umymmqY  (讲的是springmvc怎么做才可以跨域) http://my.oschina.net/ ...

  2. 从PRISM开始学WPF(一)WPF-更新至Prism7.1

    原文:从PRISM开始学WPF(一)WPF-更新至Prism7.1 我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的 ...

  3. 当我们访问不了虚拟机上ip上的web页面,是因为在window上要添加映射

    在主机上添加映射步骤 1.打开C盘 注意:用nopedata++打开 保存即可!

  4. leetcode笔记--2 reverse string

    my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...

  5. 【数据库】 SQL 常用语句

    [数据库] SQL 常用语句 1.批量导入 INSERT INTO Table2(field1,field2,...) SELECT value1,value2,... FROMTable1 要求目标 ...

  6. MySQL源码中的String

    适用于离开作用域就销毁的字符串.

  7. 对工具的反思 & deadlines与致歉

    人和动物最大的区别就是使用工具的水平. 有些人只凭着对工具的熟练掌握便成了牛人. 工具,到底应该以何种态度去看待? 在我小的时候,工具仅仅是指树枝.线.粉笔,可以让自己有更多游戏可玩:上学之后,便又有 ...

  8. 谷歌js编码规范解析

    http://alloyteam.github.io/JX/doc/specification/google-javascript.xm 阅读了谷歌js编码规范,我发现了很多,js的里面很多要注意的问 ...

  9. 名字管理系统demo

    # 名字管理系统demo # 打印功能提示 print('欢迎使用名字管理系统v6.6.6') print('1:添加一个名字') print('2:删除一个名字') print('3:修改一个名字' ...

  10. nmon Analyser分析仪

    nmon Analyser官网: https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Power+System ...