자바스크립트로 달력 만들기

MINKY·2023년 2월 17일
0

자바스크립트

목록 보기
1/1
post-thumbnail

완성 결과물!

https://bigtop.tistory.com/71 님의 블로그를 참고하여 작성하였습니다

수정해야 할 점

  • 눌렀을때 그리드가 이상해짐... 왤까
  • 일정 넣기 기능 추가
  • 크기 변경 필요

자바스크립트 코드

// 달력 만들기

let date = new Date();

const renderCalendar = () => {

  const viewYear = date.getFullYear(); // 해당 년 받아오기
  const viewMonth = date.getMonth(); // 해당 월 받아오기

  var monthNames = ["January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  ]; // 달 이름을 영어로 출력하기 위한 배열

  document.querySelector(".year-month").textContent = `${viewYear} ${monthNames[viewMonth]}`;

  const prevLast = new Date(viewYear, viewMonth, 0); // 지난달의 마지막 날 Date 객체
  const thisLast = new Date(viewYear, viewMonth + 1, 0); // 이번달의 마지막 날 Date 객체

  const PLDate = prevLast.getDate(); // 지난달의 마지막 날짜
  const PLDay = prevLast.getDay(); // 지난달의 마지막 요일

  const TLDate = thisLast.getDate(); // 이번달의 마지막 날짜
  const TLDay = thisLast.getDay(); // 이번달의 마지막 요일

  // 날짜들을 담아둘 배열
  const prevDates = []; // 이전달 날짜
  const thisDates = [...Array(TLDate + 1).keys()].slice(1);
  const nextDates = []; // 다음달 날짜

  // Array(n) => 길이가 n인 배열 생성
  // keys() => 0부터 n -1 까지의 배열 반복자 생성(내부요소 순회) ==> 이번달 마지막 날짜 + 1을 n에 전달
  // slice(1) => 제일 앞에 있는 0을 없애기 위해

  if (PLDay !== 6) { // 이전 달을 표현할 날짜 생성 (지난달 마지막 요일이 토요일(6) 이면 굳이 그릴 그릴 필요 없음)
    for (let i = 0; i < PLDay + 1; i++) {
      prevDates.unshift(PLDate - i);
    }
  }

  //unshift() => 배열의 앞에 아이템을 추가한다. 새로운 요소를 배열의 맨 앞쪽에 추가하고 새로운 길이 반환
  // 0부터 시작해서 지난달 마지막 요일이 될 때까지 반복하게 작성, 지난달의 마지막 날짜부터 1씩 줄어든 값을 배열 앞쪽으로 채워넣음

  for (let i = 1; i < 7 - TLDay; i++) {
    nextDates.push(i); // 이번달 마지막 날짜의 요일을 기준으로 필요한 개수를 파악해서 1부터 1씩 증가시키며 하나씩 채워넣음
  }

  // push() => 배열의 끝에 하나 이상의 요소를 추가하고 배열의 새로운 길이 반환
  const dates = prevDates.concat(thisDates, nextDates); // concat 메서드를 통해서 세 배열을 합침
  const firstDateIndex = dates.indexOf(1); // 지난달 부분을 알아내기 위함
  const lastDateIndex = dates.lastIndexOf(TLDate); // 다음달 부분을 알아내기 위함

  dates.forEach((date, i) => { // 이전달과 다음달 부분의 투명도 조절 위함
    const condition = i >= firstDateIndex && i < lastDateIndex + 1
                      ? 'this' // 이번달
                      : 'other'; // 나머지 (span대그로 감싸 classa 로 지정)
    dates[i] = `<button class="date"><span class="${condition}">${date}</span></button>`;
  })

  document.querySelector('.dates').innerHTML = dates.join('');

  const today = new Date(); // 오늘 날짜 표기하기 위해
  if (viewMonth === today.getMonth() && viewYear === today.getFullYear()) { // 현재 월을 보고 있는게 맞는지
    for (let date of document.querySelectorAll('.this')) { // this 태그 찾기
      if (+date.innerText === today.getDate()) { // +연산자로 숫자로 변경
        date.classList.add('today'); // 해당 태그에 today 클래스 추가
        break;
      }
    }
  }
}

renderCalendar();

const prevMonth = () => {
  date.setDate(1); // 1일로 날짜를 먼저 설정 (31일이 포함된 달의 경우 31일이 넘어가게 되기 때문!)
  date.setMonth(date.getMonth() - 1);
  renderCalendar();
}

const nextMonth = () => {
  date.setDate(1);
  date.setMonth(date.getMonth() + 1);
  renderCalendar();
}

const goToday = () => {
  date = new Date();
  renderCalendar();
}

0개의 댓글