• 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,渲染出你想要的日历!

  • 相关阅读:
    button 垂直分布
    GitHub上值得关注的iOS开源项目
    电脑连接网络(网络正常),但不能上网,登录网页提示dns_probe_finished_no_internet
    android 模拟应用因内存不足被后台杀死命令
    android 屏幕划分
    android 没有root的手机导出数据库
    移动硬盘不能识别,设备管理器中显示黄色感叹号
    低功耗蓝牙开发(BLE)
    音视频学习笔记
    Java中为什么要使用线程池?如何使用?
  • 原文地址:https://www.cnblogs.com/JRliu/p/8884801.html
Copyright © 2020-2023  润新知