前端学习笔记 - 如何实现一个日历

记录一下,这两天写的一个日历实现的思路

  1. 思路

    一般的日历都是这样的

    主要的几点:

    1. 当前月有多少天
    2. 当前月的第一天是星期几
    3. 当前月的最后一天是星期几
  2. 实现

    1. 获取月的天数

      function getOneMonthDays (year, month) {
          return new Date(year, month, 0).getDate()
      }
      复制代码
    2. 获取某天的星期数

      function getDayOfWeek (year, month, day) {
          return new Date(year, month - 1, day).getDay()
      }
      复制代码
    3. 生成日期数组

      有了这两个方法就可以生成每个月的日期数组了

      // 这个用来填充日期列表
      function setDateListItem ({ year, month, date, dateTableIndex }) {
          return {
              dateStamp: `${year}/${month}/${date}`,
              date,
              cnWeek: dateTable.cnWeek[dateTableIndex],
              cnWeekShort: dateTable.cnWeekShort[dateTableIndex],
              enWeek: dateTable.enWeek[dateTableIndex],
              enMonth: dateTable.enMonth[month - 1]
          }
      }
      // 日期数组中每一项的内容
      const dateTable = {
          cnWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
          cnWeekShort: ['日', '一', '二', '三', '四', '五', '六'],
          enWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
          enMonth: [
              'January', 'February', 'March', 'April', 'May',
              'June', 'July', 'August', 'September', 'October',
              'November', 'December'
          ]
      }
      
      // 设置日期数组
      function setDateList (year, month) {
          const currentMonthDays = getOneMonthDays(year, month)
          const firstDayInCurrentMonth = getDayOfWeek(year, month, 1)
          const dateList = []
      
          /*
            如果当前月不是从星期日开始,从上个月补全,因为
            我是从周日开始,getDay也是从0开始到6,所以这里判断
            当前月的第一天不是0,也就是不是周日,那么它前面就需要
            补上个月的日期。
          */
          if (firstDayInCurrentMonth !== 0) {
              // 这里要判断1月的情况,1月的上个月就成去年的12月了
              const isPrveYear = (month - 1) === 0
              const prevMonth = isPrveYear ? 12 : month - 1
              const currentYear = isPrveYear ? year - 1 : year
              const prveMonthDays = getOneMonthDays(currentYear, prevMonth)
              // 这里是补上个月的,所以从上个月的最后开始补
              for (let i = firstDayInCurrentMonth - 1; i >= 0; i -= 1) {
                  const index = getDayOfWeek(currentYear, prevMonth, prveMonthDays - i)
                  dateList.push(
                      setDateListItem({
                          year: currentYear,
                          month: prevMonth,
                          date: prveMonthDays - i,
                          dateTableIndex: index
                      })
                  )
              }
          }
          
          // 当月日期添加,这里就没什么好说的,直接循环就行了
          for (let i = 0; i < currentMonthDays; i += 1) {
              const index = getDayOfWeek(year, month, 1 + i)
              dateList.push(
                  setDateListItem({
                      year,
                      month,
                      date: i + 1,
                      dateTableIndex: index
                  })
              )
          }
      
          const currentDateListLen = dateList.length
          /*
          当月结束时未填满整个行, 这里用了余数来判断,因为有时候是35个,
          有时候是42个,所以只要前面的日期数组余7不等于0,那么证明没有
          填满,需要下个月的天数来补
          */
          if (currentDateListLen % 7) {
              const total = currentDateListLen + (7 - (currentDateListLen % 7))
              const diff = total - currentDateListLen
              const isNextYear = (month + 1) > 12
              const nextMonth = isNextYear ? 1 : month + 1
              const currentYear = isNextYear ? year + 1 : year
              for (let i = 0; i < diff; i += 1) {
                  const index = getDayOfWeek(currentYear, nextMonth, 1 + i)
                  dateList.push(
                      setDateListItem({
                          year: currentYear,
                          month: nextMonth,
                          date: i + 1,
                          dateTableIndex: index
                      })
                  )
              }
          }
      
          return dateList
      }
      复制代码

    测试一下

    应该是没啥问题的,这就可以拿到每个月的日期数组,然后就是细节了,样式啊之类的。

    这里就做了个小demo。具体长这样

    代码在这里

    github

    后面一段时间,要开启node.js之旅了。感觉学的东西好多啊。

转载于:https://juejin.im/post/5bd6de465188250ef70596d1

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值