부트캠프 수료 후 게으른 일상을 보내고 있는 어느날 이렇게 살면 안 된다는 생각이 들어 할 일을 적어내려가는 투두리스트를 작성하려고 했다. 그런데 문득 내가 쓰는 투두리스트 엡을 내 손으로 만들면 재밌을 것 같다는 생각이 들어 당장 만들기 시작했다.
리액트를 이용해서 만들어볼까? 하는 생각도 했지만 굳이 한 페이지 짜리 웹에서 리액트를 쓸 필요성을 느끼지 못했다. 그리고 플젝을 하면서 리액트 위주로 쓰다보니 또 바닐라JS가 어색해지는 무한의 굴레에서 벗어나기 위해 이번 캘린더-투두리스트는 바닐라JS로만 만들어보기로했다. (그리고 사실 내 노트북에서 리액트 파일 켜는데만 한 세월이라 조금 부담스럽다 ㅠ..)
얼추 이런 느낌의 단순히 캘린더와 투두리스트를 합친 할 일 관리 웹을 만들고 싶었다.
후에 구체적인 색상이나 레이아웃을 정하기 위해 피그마를 켜서 적당히 네모네모하게 만들었다. 딱히 다른 기능은 당장 생각이 안나서 우선 이 정도로만 정해놓고 vscode를 켰다.
위 피그마와 큰 차이 없어 보이지만 완성한 것이다.
아직 캘린더만 만들었는데 모든 기능을 다 만들고 블로그를 쓰려하니 까먹을 것 같아 캘린더 코드만 써보려고 한다.
해당 코드는 17분 안에 자바스크립트로 달력 만들기 << 이 영상을 참고하여 만들었다. 처음부터 혼자 만들어야 더욱 의미있겠으나 그러다가 막히면 영영 놔버릴 것 같아 완성에 의의를 두고 시작하기로 했다. 코드를 이해하면서 진행하고 싶었기 때문에 주석이 가득하다.
<section class='cal'>
<div class='header'>
<button class="nav-btn go-prev" onclick='prevMonth()'><</button>
<div class="year-month"></div>
<button class="nav-btn go-next" onclick='nextMonth()'>></button>
<button class="nav-btn go-today" onclick='goToday()'>Today</button>
</div>
<div class='main'>
<div class="days">
<div class="day">SUN</div>
<div class="day">MON</div>
<div class="day">TUE</div>
<div class="day">WED</div>
<div class="day">THU</div>
<div class="day">FRI</div>
<div class="day">SAT</div>
</div>
<div class="dates"></div>
</div>
</section>
캘린더 부분의 마크업이다. 원래는 nav를 이용하여 월 이동과 오늘날짜로 이동하는 방식이었으나 nav를 없애버렸다.
달력을 보여주는 renderCalendar
함수를 만들고 그 안에서 달력을 보여주는 코드를 짠다
new Date()
를 이용해 오늘 날짜를 가져온다- 현재 연월을 표시하는
viewYear
와viewMonth
를 만들고 연과 월만 각각 할당한다. (getMonth는 0부터 시작이므로 이번달을 구하려면 +1 해줘야한다)- 화면에
textContent
를 이용하여 '2022년 1'월 과 같은 형태로 출력한다- 달력에는 이번달만 있는게 아니라 이전달과 다음달이 흐리게 표시될 예정이므로 지난달 마지막날과 이번달 마지막날을 구해준다.
각각의 배열을 만들어준 후 합쳐준다
const thisDates = [...Array(TLDate + 1).keys()].slice(1)
에서 인덱스는 0부터 시작하므로 TLDate에 +1 해주어 요소 하나가 추가된 배열을 만들고,slice(1)
을 이용해 1일부터 마지막날까지의 배열로 만든다.- 지난달 마지막 요일이 토요일이 아니면 (요일 시작이 일요일부터니까) 지난달 날짜들을 넣어준다
concat
으로 지난달 이번달 다음달 배열을 합쳐준다.
- date의 인덱스가 이번달 1일 인덱스보다 크거나 같고 막날 인덱스보다 작으면 this, 아니면 other 클래스를 부여한다. 다른달은 opacity 흐리게 해주기 위함
forEach
이용하여 dates 배열의 item을 각각의 div 태그에 뿌려준다.<div class='dates'></div>
안에innerHTML
이용하여 dates 배열을 string으로 출력한다.
- 지금 보고있는 달력이 이번년 이번달 달력이면
this
라는 클래스를 갖고있는 값을 돌려서, date의 text가 오늘 날짜와 같으면 (string에 + 붙여줘서 type을 number로 바꿔줌)today
라는 클래스를 붙여준다break
이용해서 조건 충족되면 반복문 빠져나오기
- 그럼 오늘 날짜에만 today 클래스가 붙으므로 이렇게 스타일을 따로 지정해줄 수 있다.
renderCalendar()
로 캘린더 출력 함수 실행하기Date.prototype.setMonth()
: setMonth () 메서드는 현재 설정된 연도에 따라 지정된 날짜의 월을 설정할 수 있다
코드를 보면 그렇게 이해가 안 될 만한 코드는 아닌데 스스로 생각하기에는 아직 너무 어려운 것 같다.. 예전에 라이브러리로 달력을 불러온 적이 있는데 이렇게 라이브러리 없이 바닐라js로만 만들어보니 생각해야할게 많아서 놀랐다.
나중에 원하는 연월일로 가는 기능(갤럭시 기본 캘린더앱처럼)이나 여러날에 걸친 일정 기능도 추가해보고싶다.
멋있습니다!! 저도 구현해보고 싶네요!