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

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

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

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

然后,神奇的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,渲染出你想要的日历!

最新文章

  1. Request 和 Response 原理
  2. linux基础知识与技能2
  3. Javascript > Eclipse > 自动代码规范化
  4. Java keytool 使用总结
  5. 根据指定Word模板生成Word文件
  6. 四、Protocol 类似java的接口
  7. 简单几何(线段相交) POJ 1410 Intersection
  8. PHP实现简单计算器
  9. “我爱淘”第二冲刺阶段Scrum站立会议1
  10. HDU 5114 Collision
  11. [CodeForce]358D Dima and Hares
  12. 【模拟】NEERC15 G Generators(2015-2016 ACM-ICPC)(Codeforces GYM 100851)
  13. Python:代码调试的好帮手sys._getframe()
  14. LINQ 内链接 左链接 右链接
  15. BHuman文档结构
  16. 取得system32文件夹下面文件的写入权限
  17. ASP.NET Web API决跨域问题
  18. matplotlib注解-【老鱼学matplotlib】
  19. java AQS(AbstractQueuedSynchronizer)同步器详解
  20. 深入C#

热门文章

  1. java加密用到了BASE64Decoder时报错信息:Access restriction: The type BASE64Encoder is not accessible due to restrict
  2. 也谈js传值和传址
  3. 实用脚本 1 -- 安装Ctags
  4. Sql Server 2008 R2数据库中插入中文变成了问号
  5. Returning Values from Bash Functions
  6. 第十五篇 Python之文件处理
  7. 9.0 toast定位+WebDriverWait显示等待
  8. Navicat oracle to postgresql ERR
  9. CSS实现自适应下保持宽高比
  10. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)