Pure JS React 日曆
使用 new Date
製作日曆
更新
:我后来改写的更加简洁,并且抽离成hook
详情可参考 前端野人
显示日期
需要注意month
是从0
开始
new Date()
当前月份 : new Date().getMonth
//0 - 11当前年份 : new Date().getFullYear
// 2020跳至下个月/上个月
程式逻辑:从当下的时间物件取得月份 控制 +1 / -1
所以要先纪录时间。
const [ today,setTody] = useState(new Date())const [currentMonth,setCurrentMonth] = useState(today.getMonth)const [currentMOnth,setCurrentYear] = useState(today.getFullYear)
因为跳至下个月是用数字加减计算,所以要有判断式判断是否大于11
或是小于0
因为表示要跳至下一年
或是前一年
下个月
const setNextMonth = () =>{ if (currentMonth === 11) { setCurrentMonth(0) setCurrentYear(currentYear + 1) } else { setCurrentMonth(currentMonth + 1) }}
上个月
const setPreMonth = () =>{ if (currentMonth === 0) { setCurrentYear(currentYear - 1) setCurrentMonth(11) } else { setCurrentMonth(currentMonth - 1) }}
月曆
月曆这部分比较麻烦,我这边是处理成二维阵列。
我们要显示每个月的天数,并且要能跟真实的日曆排版一致。
下面程式可以依照年份及月份显示组合成月曆天数的二维阵列
firstDay
, 为每个月的1号是在星期几days
, 为一个月的天数。date = 1
, 为每个月的1号。weekNum
,控制每个星期的数量。days 计算
为什么days
要用 32 - new Date(year, month, 32).getDate()
原因在于,我们并不知道当月的天数,但我们知道一个月最多只有31天,所以new Date(year, month, 32).getDate()
为下个月的天数,我们再用32 - 下个月多出来的天数
就可以知道这个月的天数。
weekNum 计算
因为一个日曆的排版可能是4 * 7
或是5 * 7
甚至可能会有6 * 7
我们不知道但,还是必须留空格给日曆排版,所以是用Math.ceil((days + firstDay) / 7)
判断日曆需要的weekNum
const daysInMonth = (year, month) => { const firstDay = new Date(year, month).getDay() const days = 32 - new Date(year, month, 32).getDate() let date = 1 let daysInMonth = [] let weekNum = (days) => { return Math.ceil((days + firstDay) / 7) } for (let i = 0; i < weekNum(days); i++) { let week = [] let day = { date: '', } for (let j = 0; j < 7; j++) { if (i === 0 && j < firstDay) { week.push(day) } else if (date > days) { week.push(day) } else { week.push({ ...day, date }) date++ } } daysInMonth.push(week) } return daysInMonth}
选择当日日期。
使用new Date
更新所选择的日期。
const isSeleted = calendar.today.getDate() === day.date && calendar.today.getMonth() === calendar.currentMonth && calendar.today.getFullYear() === calendar.currentYearconst setSelectDate = () => { let getDate = new Date( calendar.currentYear, calendar.currentMonth, day.date, ) calendar.selectToday(getDate)}
Demo
Reference
https://medium.com/@nitinpatel_20236/challenge-of-building-a-calendar-with-pure-javascript-a86f1303267d
本系列是由参与 Menswalk 时所做的功能逻辑,详情可持续follow :https://github.com/antijava/menswalk