iT邦幫忙

1

MensWalk - Pure React Calendar

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.currentYear

const setSelectDate = () => {
  let getDate = new Date(
      calendar.currentYear,
      calendar.currentMonth,
      day.date,
  )
  calendar.selectToday(getDate)
}

Demo

Edit react-pure-calendar

Reference

https://medium.com/@nitinpatel_20236/challenge-of-building-a-calendar-with-pure-javascript-a86f1303267d


本系列是由參與 Menswalk 時所做的功能邏輯,詳情可持續follow :https://github.com/antijava/menswalk



尚未有邦友留言

立即登入留言