본문 바로가기
카테고리 없음

[VanilaJS] Calendar + Mini Calendar

by HIIDO 2023. 10. 13.
반응형

참고한 영상

https://www.youtube.com/watch?v=Z1BGAivZRlE

https://www.youtube.com/watch?v=b6473PrT-dU&t=296s

 

 

최종 결과물

 

 

전체 코드

https://github.com/hido02/calendar

 

GitHub - hido02/calendar

Contribute to hido02/calendar development by creating an account on GitHub.

github.com

 

 

요구사항

  • 현재 년도와 월에 해당하는 달력 표시
  • 달력에 오늘 날짜는 강조 표시된다
  • 이전 및 다음 아이콘을 클릭하면 이전 달 또는 다음 달의 달력이 표시된다
  • 미니 달력은 현재 년도와 월, 일, 요일을 표시한다

 

HTML 요소 선택

const daysTag = document.querySelector(".days");
const currentDate = document.querySelector(".current-date");
const prevNextIcon = document.querySelectorAll(".icons span");

querySelector를 사용해서 클래스 요소들을 선택한다

 

현재 날짜 정보 가져오기

let date = new Date();
let currYear = date.getFullYear(); // 현재 년도
let currMonth = date.getMonth(); // 현재 월 (0부터 시작)
let currDay = date.getDate(); // 현재 일
let currDayOfWeek = date.getDay();

Date 객체를 사용해 현재 날짜와 시간 정보를 가져온다

 

월 이름 배열 생성

const months = ["January", "February", "March", "April", "May", "June", "July",
              "August", "September", "October", "November", "December"];

12개의 월 이름을 저장

 

캘린더를 화면에 표시하기

const renderCalendar = () => {
    let firstDayofMonth = new Date(currYear, currMonth, 1).getDay();
    let lastDateofMonth = new Date(currYear, currMonth + 1, 0).getDate();
    let lastDayofMonth = new Date(currYear, currMonth, lastDateofMonth).getDay();
    let lastDateofLastMonth = new Date(currYear, currMonth, 0).getDate();
    let liTag = "";

    for (let i = firstDayofMonth; i > 0; i--) {
        liTag += `<li class="inactive">${lastDateofLastMonth - i + 1}</li>`;
    }

    for (let i = 1; i <= lastDateofMonth; i++) {
        let isToday = i === date.getDate() && currMonth === date.getMonth() && currYear === date.getFullYear() ? "active" : "";
        liTag += `<li class="${isToday}">${i}</li>`;
    }

    for (let i = lastDayofMonth; i < 6; i++) {
        liTag += `<li class="inactive">${i - lastDayofMonth + 1}</li>`;
    }
    currentDate.innerText = `${months[currMonth]} ${currYear}`;
    daysTag.innerHTML = liTag;
}

현재 날짜인지 여부를 확인하고 현재 날짜라면 active 클래스를 통해 강조

currentDate 요소에 현재 월과 년도 정보를 표시

마지막으로 daysTag에 innerHTML로 달력을 표시

 

function generateCalendar() {
    currentDateElement.textContent = `${months[currentMonth]} ${currentYear}`;

    const firstDayOfMonth = new Date(currentYear, currentMonth, 1);
    const lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0);

    daysElement.innerHTML = '';

    for (let i = 0; i < firstDayOfMonth.getDay(); i++) {
        daysElement.innerHTML += '<li></li>';
    }

    for (let day = 1; day <= lastDayOfMonth.getDate(); day++) {
        daysElement.innerHTML += `<li${day === date.getDate() && currentMonth === date.getMonth() && currentYear === date.getFullYear() ? ' class="active"' : ''}>${day}</li>`;
    }
}

현재 월의 달력을 생성하고 daysElement 요소에 표시

firstDayOfMonth와 lastDayOfMonth를 사용해서 해당 월의 첫 번째 날에서 마지막 날까지 날짜를 생성

화면에서 표시되지 않는 공백 <li> 요소도 생성해서 요일을 정렬한다.

 

미니 캘린더

function generateMiniCalendar() {
    const miniCalendarDate = document.getElementById("date");
    const miniCalendarDay = document.getElementById("day");
    const miniCalendarMonth = document.getElementById("month");
    const miniCalendarYear = document.getElementById("year");

    const daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    const currDayOfWeek = daysOfWeek[new Date(currYear, currMonth, currDay).getDay()];

    miniCalendarDate.innerHTML = currDay; // 일
    miniCalendarDay.innerHTML = currDayOfWeek; // 요일
    miniCalendarMonth.innerHTML = months[currMonth]; // 월
    miniCalendarYear.innerHTML = currYear; // 년
}

generateMiniCalendar();

 

이벤트 처리

prevNextIcon.forEach(icon => {
    icon.addEventListener("click", () => {
        currMonth = icon.id === "prev" ? currMonth - 1 : currMonth + 1;

        if (currMonth < 0 || currMonth > 11) {
            date = new Date(currYear, currMonth, new Date().getDate());
            currYear = date.getFullYear();
            currMonth = date.getMonth();
        } else {
            date = new Date();
        }
        renderCalendar();
        generateMiniCalendar();
    });
});

 

반응형