js实现日历

Posted 大泽队长

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js实现日历相关的知识,希望对你有一定的参考价值。

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

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

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

然后,神奇的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实现日历的主要内容,如果未能解决你的问题,请参考以下文章

原生JS实现日历

原生js简易日历效果实现

帮忙改一下js日历的日期的显示格式

原生Js_制作简易日历

基于python实现UI自动化3.4 JS 处理日历控件(删除 readonly 属性)

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