ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JS/Calendar] 바닐라 자바스크립트로 달력 구현하기
    Frontend 2019. 6. 26. 15:00

    오늘은 바닐라 자바스크립트로 캘린더 구현하는 방법을 포스팅해보려고 한다.

     

     

    캘린더 모양은 대충 이렇게 생겼고,

    오늘 날짜는 노란색 동그라미로 표시된다.

     

     

    그리고 특정 날짜를 클릭하면 해당 날짜가 다른 색깔로 표시되고

    왼쪽 사각형에 있는 날짜와 요일이 클릭한 날짜로 바뀌어야 한다.

     

     

    See the Pen calendar by juyeonH (@JY712) on CodePen.

     

     

    해당 기능을 구현한 코드는 위에 codepen으로 올렸고,

    몇 가지 코드만 어떻게 구현했는지 적으려고 한다.

     

    const init = {
      monList: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      dayList: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
      today: new Date(),
      monForChange: new Date().getMonth(),
      activeDate: new Date(),
      getFirstDay: (yy, mm) => new Date(yy, mm, 1),
      getLastDay: (yy, mm) => new Date(yy, mm + 1, 0),
      nextMonth: function () {
        let d = new Date();
        d.setDate(1);
        d.setMonth(++this.monForChange);
        this.activeDate = d;
        return d;
      },
      prevMonth: function () {
        let d = new Date();
        d.setDate(1);
        d.setMonth(--this.monForChange);
        this.activeDate = d;
        return d;
      },
      addZero: (num) => (num < 10) ? '0' + num : num,
      activeDTag: null,
      getIndex: function (node) {
        let index = 0;
        while (node = node.previousElementSibling) {
          index++;
        }
        return index;
      }
    };

     

    먼저 나는 이렇게 객체를 만들었다.

    today에는 오늘 날짜를 담고, 다음 버튼을 클릭하면 객체의 nextMonth 함수를 실행시키는데,

    이 함수는 지금 해당하는 달을 1 증가시킨 후 그 숫자를 새로 가져온 날짜 객체 d에 d.setMonth()로 설정한다.

    이 때, d.setDate(1)로 일자를 1일로 세팅해주는데, 

    그 이유는 만약에 내가 5월 31일에 nextMonth 함수를 실행시켜 달만 6월로 바꿔줄 경우

    6월에는 30일까지밖에 없으므로 자동으로 7월 1일로 변경될 수 있기 때문이다.

     

    + 어떤 달의 첫번째 날에 대한 정보를 얻으려면 new Date(yy, mm, 1)을 해주면 되고 

    마지막 날에 대한 정보를 얻으려면 new Date(yy, mm + 1, 0)을 해주면 된다.

    여기서 mm값은 new Date.getMonth()한 값으로 '해당 월 - 1'이다.

     

     

     

    /**
     * @param {date} fullDate
     */
    function loadYYMM (fullDate) {
      let yy = fullDate.getFullYear();
      let mm = fullDate.getMonth();
      let firstDay = init.getFirstDay(yy, mm);
      let lastDay = init.getLastDay(yy, mm);
      let markToday;  // for marking today date
      
      if (mm === init.today.getMonth() && yy === init.today.getFullYear()) {
        markToday = init.today.getDate();
      }
    
      document.querySelector('.cal-month').textContent = init.monList[mm];
      document.querySelector('.cal-year').textContent = yy;
    
      let trtd = '';
      let startCount;
      let countDay = 0;
      for (let i = 0; i < 6; i++) {
        trtd += '<tr>';
        for (let j = 0; j < 7; j++) {
          if (i === 0 && !startCount && j === firstDay.getDay()) {
            startCount = 1;
          }
          if (!startCount) {
            trtd += '<td>'
          } else {
            let fullDate = yy + '.' + init.addZero(mm + 1) + '.' + init.addZero(countDay + 1);
            trtd += '<td class="day';
            trtd += (markToday && markToday === countDay + 1) ? ' today" ' : '"';
            trtd += ` data-date="${countDay + 1}" data-fdate="${fullDate}">`;
          }
          trtd += (startCount) ? ++countDay : '';
          if (countDay === lastDay.getDate()) { 
            startCount = 0; 
          }
          trtd += '</td>';
        }
        trtd += '</tr>';
      }
      $calBody.innerHTML = trtd;
    }

     

    그리고 이제 동적으로 달력의 일자 부분을 출력하는 함수이다.

    처음 캘린더를 로드할 때, 달력의 이전, 다음 버튼을 클릭할 때 함수를 실행한다.

     

    날짜가 처음 시작하면 startCount 변수를 0에서 1로 변경하고

    날짜 세는 것이 끝나면 startCount 변수를 다시 0으로 초기화한다.

     

    만약에 표시할 달력의 년도/월이 오늘 날짜의 년도/월과 일치하면 

    markToday 변수에 오늘 날짜의 일자를 할당한 후

    countDay 변수가 markToday 값과 일치하면 td에 today 클래스를 준다.

     

     

     

    반응형

    COMMENT