상세 컨텐츠

본문 제목

[Javascript] Calendar & To-do List ③Express Holidays

Experience/[Javascript] Calendar + To-do List

by winCow 2021. 5. 13. 11:46

본문

1. 개요

공휴일을 표시하는 기능을 추가하고, 오늘 날짜를 표시했다.

 

 

 

2. CSS

#holiday {
  color: #eb3b5a;
}
#today {
  background-color: #f78fb3;
  border-radius: 100%;
  height: 24px;
  width: 24px;
  margin: 10px calc(100%/7/2 - 12px - 10px);
  padding: 10px;
}

공휴일의 색깔을 표시하기 위한 holiday id와 오늘 날짜를 표시하기 위한 today id의 내용이다. 이전 포스팅에서 토요일이 빨간색으로 덮어씌워지지 않는 이유는 자바스크립트의 문제가 아닌 css 적용 우선순위의 문제였다. holiday class와 :nth-child 수도클래스의 적용 우선순위가 같은데, 이 경우에는 해당 클래스를 가진 요소의 개수가 많은 쪽이 적용된다. 즉, 표시되는 모든 토요일에 적용되는 :nth-child가 공휴일인 토요일에만 적용되는 holiday class보다 개수가 많으므로 holiday 클래스의 색상이 적용되지 않았던 것이다. 그래서 보다 우선적으로 적용되는 id를 이용했다.

today 역시 하나의 div만을 선택하므로, 같은 이유로 class를 추가해도 적용되지 않을 것이라 판단하여 id를 이용했다. 또, 원 모양의 색깔을 넣기 위해 height, width를 같은 크기로 입력했고, padding과 margin의 위 아래를 10px씩 나누어 주었다. 오늘 외의 다른 일자들은 위아래로 margin을 20px씩 가지고 있다. padding이 없으면 글자와 딱 맞는 크기의 원이 나오므로 보기에 좋지 않고, 적당히 감싸는 형태를 만들기 위해 10px를 준 뒤, margin으로 다른 요소들과의 간격을 맞춘 것이다.

또, width도 줄어들었으므로, margin으로 좌우 요소들과의 간격을 조절했다. margin은 좌우 양쪽으로 적용되므로 원래 width인 100%/7을 2로 나누었다. 거기에, 새롭게 적용한 width인 24px, 좌우 패딩의 합인 20px를 2로 나누어 빼 줌으로써, 뷰포트의 크기에 관계없이 다른 요소들과 동일하게 거리를 유지하게 되었다.

 

 

3. Javascript: 공휴일 표시

const holidays = [
  {
    'name': '신정',
    'month': 1,
    'date': 1
  },
  {
    'name': '삼일절',
    'month': 3,
    'date': 1
  },
  {
    'name': '어린이날',
    'month': 5,
    'date': 5
  },
  {
    'name': '현충일',
    'month': 6,
    'date': 6
  },
  {
    'name': '광복절',
    'month': 8,
    'date': 15
  },
  {
    'name': '개천절',
    'month': 10,
    'date': 3
  },
  {
    'name': '한글날',
    'month': 10,
    'date': 9
  },
  {
    'name': '크리스마스',
    'month': 12,
    'date': 25
  }
];
function expressHolidays() {
  const alldates = Array.from(document.querySelectorAll('.dates'));
  const theseHolidays = holidays.filter(holiday => 
    holiday['month'] == month + 1
    );
  const holiDates = theseHolidays.map(thisHoliday => thisHoliday.date);
  alldates
    .filter(data => holiDates.includes(parseInt(data.innerText)))
    .map(data => data.id = 'holiday');
}
expressHolidays();

먼저 holidays 배열에 양력 공휴일 데이터들을 입력한 뒤, expressHolidays 함수를 작성한다. 

expressHolidays는 dates 클래스를 가진 모든 요소를 선택하는데, querySelectorAll은 Nodelist를 반환하므로 배열로 바꾸어 주었다. theseHolidays는 holidays 배열에서 'month' 키에 대한 값이 이번 달과 일치하는 요소만을 선택하여 반환한다. holiDates는 이를 다시 map을 이용해 date만을 추출해낸 배열로 반환한다. 굳이 두 개의 변수를 할당할 필요는 없어 보이지만 작성 시에 헷갈려서 다른 변수에 할당했다.

이번 달의 페이지에 표시되는 모든 일자들을 요소로 가지는 alldates 배열에 filter를 걸어, 위의 holidates, 즉 이번 달의 공휴일 일자에 포함되는지를 체크하고, 해당되는 일자에만 holiday id를 추가한다.

expressHolidays 함수는 페이지가 실행되었을 때에도 실행되지만, goToPrevMonth, goToNextMonth가 실행되었을 때에도 실행되어야 하므로 두 함수의 마지막 줄에도 expressHolidays를 실행시키도록 코드를 입력해 두었다.

 

 

4. Javascript: 오늘 표시

const alldates = Array.from(document.querySelectorAll('.dates'));
const today = alldates.find(data => data.innerText == date);
today.id = 'today';

오늘 날짜를 표시하기 위해, alldates를 선택하고, 이 중에서 innerText가 date와 일치하는 값을 찾은 후, today id를 추가했다.

 

 

5. 개선점

 - 다른 월로 이동했다가 이번 월로 돌아오면 오늘을 표시한 원이 사라져 있다. id가 없어진 것으로 보인다.

 - 음력 공휴일은 음력 계산 알고리즘을 필요로 하는 것 같다.

관련글 더보기

댓글 영역