코딩 개발/Javascript

[JavaScript] 달력 구현2

호소세 2023. 12. 23. 22:47
728x90
반응형

예전에도 달력 구현을 한 적이 있는데, 에러가 나서 아쉬웠던 적이 있습니다.

https://pabeba.tistory.com/12

 

Javascript - 달력 구현

Javascript를 이용해서 웹 페이지에 달력 구현을 해보았습니다. 개인적으로 너무 어렵기 떄문에 더 자세히 분석을 해봐야겠습니다. 또한, 구현은 했지만 오류가 있는 달이 있어... 우울합니다. 부족

pabeba.tistory.com

 

이번에는 조금 더 간단?하고 에러가 나지 않게 구현해보려고 합니다.

 

달력 구현하기(Version. 02)

1. HTML 코드 작성

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
    integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  ></script>
  <body>
    <div class="schedule-header" style="text-align: center">
      <span class="weekly-picker">
        <span style="cursor: pointer" onclick="changeMonth('prev');">&lt; </span
        ><span id="calendar_year_month" tabindex="0"></span
        ><span style="cursor: pointer" onclick="changeMonth('next')">
          &gt;</span
        ></span
      >
    </div>
    <div class="calendar-body">
      <div class="calendar-week-day" tabindex="0">
        <div>일</div>
        <div>월</div>
        <div>화</div>
        <div>수</div>
        <div>목</div>
        <div>금</div>
        <div>토</div>
      </div>
      <div class="calendar-days" id="calendar_days" tabindex="0"></div>
    </div>
  </body>

 

1. jquery를 이용하여 script 함수를 만들었기 때문에 CDN으로 jquery를 다운로드합니다.

 

2. 월(month)을 변경하는 헤더 부분과 달력을 나타내는 body 부분으로 나누어 줍니다.

 

2. CSS 작성

  <style>
    .calendar-body {
      flex: 1;
      width: 100%;
    }

    .calendar-week-day {
      height: 26px;
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      font-weight: 500;
      background: #f1f1f7;
      border-radius: 13px;
    }

    .calendar-week-day div {
      display: grid;
      place-items: center;
    }

    .calendar-header {
      font-size: 25px;
      font-weight: 600;
      padding: 0 5%;
    }

    .calendar-week-day div:nth-child(7n + 1) {
      color: #ed4b48;
    }

    .calendar-week-day div:nth-child(7n) {
      color: #3e5fd2;
    }

    .calendar-days {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 0;
      margin-top: 5px;
    }

    .calendar-days > div > span {
      min-width: 24px;
      text-align: center;
    }

    .calendar-days > div {
      display: flex;
      align-items: center;
      flex-direction: column;
      height: 24px;
      margin: 3px 0;
      padding: 0 1px;
      line-height: 1.4em;
      position: relative;
      cursor: pointer;
    }

    .calendar-days.no_cursor > div {
      cursor: default !important;
    }

    .calendar-days div:nth-child(7n + 1) {
      color: #ed4b48;
    }

    .calendar-days div:nth-child(7n) {
      color: #3e5fd2;
    }
  </style>

 

1. header랑 body는 차근차근 읽어보시면 됩니다.

 

2. 일요일과 토요일에는 각각 빨간색과 파란색을 넣으면 됩니다.

 

3. JavaScript 작성

  <script>
    let thisYear = new Date().getFullYear(); //오늘 연도
    let thisMonth = new Date().getMonth() + 1; //오늘 월
    $(document).ready(function () {
      setCalendarData(thisYear, thisMonth);
    });

    // 월 변경 함수
    function changeMonth(status) {
      if ("prev" == status) {
        if (thisMonth == 1) {
          thisMonth = 12;
          thisYear = thisYear - 1;
        } else {
          thisMonth = thisMonth - 1;
        }
      }

      if ("next" == status) {
        if (thisMonth == 12) {
          thisMonth = 1;
          thisYear = thisYear + 1;
        } else {
          thisMonth = thisMonth + 1;
        }
      }
      setCalendarData(thisYear, thisMonth);
    }

    // 달력 표시
    function setCalendarData(year, month) {
      const lastDay = new Date(year, month, 0).getDate() * 1; //마지막 날 일수
      const startDay = new Date(year, month - 1, 1, 0, 0, 0, 0); //시작일
      const firstDay = startDay.getDay() * 1; //시작일 요일
      const maxDay = Math.ceil((firstDay + lastDay) / 7) * 7; // 달력에 표시될 총 일수

      let html = "";
      let dateHtml = "";
      if (month < 10) {
        month = "0" + month;
      }

      for (var i = 1; i <= maxDay; i++) {
        let dayNum = i - firstDay;
        //dayNum 값이 조건에 맞으면 값을 표시해주고, 없으면 빈칸
        let day = dayNum <= lastDay && dayNum > 0 ? dayNum : "";

        html += '<div tabindex="0"><span>';
        html += day + "</span></div>";
      }

      $("#calendar_year_month").html(thisYear + "년 " + month + "월");
      $("#calendar_days").html(html);
    }
  </script>

 

1. 월 변경하는 함수인 changeMonth는 읽어보시면 아시겠지만, 이전 버튼을 누르면 1달 전으로 이동하고

다음 버튼을 누르면 1달 후로 이동하면서 달력을 그리게 됩니다.

 

2. 달력에 표시하는 함수인 setCalendarData에 대하여 알아보겠습니다.

 

3. 해당 월의 시작일의 요일 숫자 A(예를 들어 23년 12월 1일의 요일은 금요일이니까 5)과

마지막 날의 일 B(예를 들어 23년 12월이면  31일)를 더하고 나누기 7 한 것을 올림하고 7을 곱한다.

이러면 달력에 표시돼야 하는 div의 칸을 구할 수 있습니다.

Math.ceil((A + B / 7)) *7

 

4. for문안에 있는 것을 분석해 보면

dayNum은 달력에 표시되기 전 검증을 할 숫자입니다.

day 변수가 진짜 달력에 표시될 숫자이고요.

그래서 dayNum이 마지막 날의 일수보다 작거나 같은 때나, 0보다 크면 달력에 표시되게 합니다.

23년 12월이면 1일 ~ 31일까지 표시되겠죠?

 

이렇게 하여 div 태그 안에 span 태그로 날짜를 표현하면 됩니다.

또한, 연도와 월을 표시해 주면 더욱 아름다운 달력이 완성되겠죠?

 

달력

 

완성본은 이렇습니다.

 

소감

최근에 제 자신에게 부족하다는 감정을 느끼게 되었습니다. 저도 인간인지라 제 자신을 속이는 행동을 하게 되더라고요. 이러한 행동을 하지 않아야 성공을 할 것 같은데 다시 한번 반성하게 됩니다.

항상 어떤 일이든 우선순위를 잘 생각해서 행동해야한다고 생각합니다. 어떤 것이 중요하고 중요하지 않은지를 말이지요.

여러분들도 시간이 괜찮으시다면 어떤 것이 먼저가 되어야할지를 생각하면서 오늘 하루를 마무리해보는 것도 좋다고 생각합니다.

 

그리고 최근에는 작은 성공의 기쁨에 대한 것을 더 크게 느꼈습니다. 인생에 재미를 느끼지 못하시는 분들이라면 작은 단위로 쪼개서 작은 성공의 기쁨을 느끼면 어떨까라는 생각을 합니다. 단순하게 그냥 오늘 알람을 맞춘 시간에 잘 일어났네~ 나이스. 샤워를 10분만에 잘 끝냈구나~ 나이스. 제 시간에 잘 출근했네~ 나이스. 뭐 이정도로 말이죠. ㅎㅎ

반응형