바닐라 JS로 투두 리스트 만들기(1): 캘린더

콩주희·2025년 3월 11일
0

내가 젤 못하는 바닐라 JS를 과제로 주다니 상황이 정말 최ㅐㅐㅐㅐㅐ악이다
투두리스트를 만들기였는데 그냥 만드는건 재미없으니까 캘린더 투두리스트를 만들어보기로 했다.

초기 세팅은 이렇다

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>todoList</title>
    <link rel="stylesheet" href="style.css" />
  </head>

캘린터 구성 index.html

  <body>
    <div class="container">
      투두리스트
      <div class="calendar">
        <div class="header">
          <button class="nav" id="prev" onClick="prevMonth()">이전</button>
          <button id="today" onClick="goCurrentMonth()"></button>
          <button class="nav" id="next" onClick="nextMonth()">다음</button>
        </div>
        <div class="main">
          <div class="days">
            <div class="day"></div>
            <div class="day"></div>
            <div class="day"></div>
            <div class="day"></div>
            <div class="day"></div>
            <div class="day"></div>
            <div class="day"></div>
          </div>
          <div class="dates"></div>
        </div>
      </div>
      <div id="modal-root"></div>
      <script type="module" src="modal.js"></script>
      <script src="calendar.js"></script>
      <script src="script.js"></script>
    </div>
  </body>

네브는 버튼으로 달을 이동시킬 수 있게 해주었다.
그리고 바디는 요일과 일자를 나누어서 구성해주었다 (아무래도 일자는 네모칸에 들어가야하기 때문에)

참고한 블로그 JS 달력 만들기

그리고 밑에는 사용해야하는 스크립트를 다 불러와주었다.
그 중 모달에서 불러오는 모듈은 import와 export를 사용할 수 있는데 모달에서 localStorage를 관리해주어야했기 때문에 사용하였다.
-> 투두리스트 2탄에서 다시 정리!

캘린더 스크립트를 살펴보자

원래 한번에 적는 코드가 200줄은 그냥 넘어갔는데 스타일 시트를 써서 그런지 60줄 밖에 안 나왔다!

그래도 분리해서 보자

const date = new Date();
현재의 시간을 date 객체로 초기화 시켜주는 명령문

const renderCalendar = () => {
  const currentYear = date.getFullYear();
  const currentMonth = date.getMonth();

캘린더를 랜더링 해준다
date에서 전체 연도와 달을 가져와준다.

document.querySelector("#today").textContent = "${currentYear}년 ${
    currentMonth + 1
  }월";
  

아까 보았던 현재로 가는 네브바에 현재 캘린더에 보이는 년월 글자를 넣어준다. (id가 today인 것을 찾아서)
캘린더 쓰니까 너무 이름이 겹치는게 많아서 좀 더 확실히 구분 해놔야겠다.

  const prevLast = new Date(currentYear, currentMonth, 0);
  const currentLast = new Date(currentYear, currentMonth + 1, 0);

newDate(년도, 월, 0) -> prevMonth의 가장 마지막 날을 반환한다

  const prevLastDay = prevLast.getDay();
  const currentLastDay = currentLast.getDay();

getDay 0~6 까지 일~토에 해당하는 숫자를 반환한다 -> 각 달의 마지막 요일을 반환하는 것

  const prevDates = [];
  const currentDates = Array.from({ length: currentLast.getDate() }, (_, i) => i + 1);
  const nextDates = [];
  if (prevLastDay !== 6) {
    for (let i = 0; i < prevLastDay + 1; i++) {
      prevDates.unshift(prevLast.getDate() - i);
    }
  }

지난 달의 마지막 요일이 토요일이 아니라면 prevDates에 오름차순으로 날짜를 넣어준다
(unshift는 계속 맨앞으로 배열을 추가해주는 것: 역 append ㅋㅋ)
만약 금요일 5라면 26(5)27(4)28(3)29(2)30(1)31(0) -> 이런식 괄호 안에 있는건 i의 값이다

  for (let i = 1; i < 7 - currentLastDay; i++) {
    nextDates.push(i);
  }

마지막주가 완전한 7일이 아니라면 다음달의 일을 추가해준다
만약 금요일(5)이라면 1만 채워지는...

const dates = prevDates.concat(currentDates, nextDates);
배열을 prevDates -> currentDates -> nextDates 순으로 만들어줍니다.

  dates.forEach((eachDate, i) => {
    const firstDate = prevDates.length;
    const lastDateIndex = prevDates.length + currentDates.length - 1;
    const condition =
      i >= firstDate && i < lastDateIndex + 1 ? `current` : `other`;
    if (
      eachDate === new Date().getDate() &&
      date.getMonth() === new Date().getMonth()
    ) {
      dates[i] = `<div class="date openModal" data-date="${currentYear}/${
        currentMonth + 1
      }/${eachDate}"><span class="today">오늘</span></div>`;
    } else {
      dates[i] = `<div class="date openModal" data-date="${currentYear}/${
        currentMonth + 1
      }/${eachDate}"><span class="${condition}">${eachDate}일</span></div>`;
    }
  });
  document.querySelector(".dates").innerHTML = dates.join("");
};

날짜 뽑아주는 forEach이다

마지막에 배열을 하나씩 나누어서(join("")으로) 내부 HTML로 설정해준다

이상으로 대충 정리한 캘린더 js 엿따

profile
쉬고 싶은 콩쥐

0개의 댓글

관련 채용 정보