[DAY - 47] #3 팀프로젝트(바닐라스크립트 달력)

2023. 5. 9. 20:18·🔥 부트캠프-웹 개발 🔥/이젠제주투어(팀프로젝트)

항공

팀프로젝트 작업중 다른 부분들은 기존에 배운 js로 가능했지만 현재 날짜를 가져와 달력을 만드는 것은 배우지 않았다.

지금 바닐라스크립트로 작성중인 반응형 웹들도 대부분 플러그인으로 쉽게 사용하는 것으로 알고있지만, 단순 불러오는 것이 아닌 알고있는 코드와 메서드들로 달력을 만들어 보고 싶었다.

순수 자바스크립트로 달력을 만드는 것은 검색해 보아도 자료가 많지 않았다. (대부분 제이쿼리 혹은 플러그인)

 

그 중 한 블로그의 글을 보고 참조하여 만들어 보았다.

 

https://sirius7.tistory.com/35

 

[Javascript] 자바스크립트를 이용하여 달력 만들기

날짜를 입력하는 웹 사이트를 만들기 위해 먼저 만들어본 달력 다른 라이브러리 등을 사용하지 않고 자바스크립트만 이용해서 만들어 봤다. 날짜 표시 이외에 만들 때 목표한 기능은 다음과 같

sirius7.tistory.com

 

    <script>
        window.onload = function () { buildCalendar(); }    // 웹 페이지가 로드되면 buildCalendar 실행

        let nowMonth = new Date();  // 현재 달을 페이지를 로드한 날의 달로 초기화
        let today = new Date();     // 페이지를 로드한 날짜를 저장
        today.setHours(0, 0, 0, 0);    // 비교 편의를 위해 today의 시간을 초기화

        // 달력 생성 : 해당 달에 맞춰 테이블을 만들고, 날짜를 채워 넣는다.
        function buildCalendar() {

            let firstDate = new Date(nowMonth.getFullYear(), nowMonth.getMonth(), 1);     // 이번달 1일
            let lastDate = new Date(nowMonth.getFullYear(), nowMonth.getMonth() + 1, 0);  // 이번달 마지막날

            let tbody_Calendar = document.querySelector(".Calendar > tbody");
            document.getElementById("calYear").innerText = nowMonth.getFullYear();             // 연도 숫자 갱신
            document.getElementById("calMonth").innerText = leftPad(nowMonth.getMonth() + 1);  // 월 숫자 갱신

            while (tbody_Calendar.rows.length > 0) {                        // 이전 출력결과가 남아있는 경우 초기화
                tbody_Calendar.deleteRow(tbody_Calendar.rows.length - 1);
            }

            let nowRow = tbody_Calendar.insertRow();        // 첫번째 행 추가           

            for (let j = 0; j < firstDate.getDay(); j++) {  // 이번달 1일의 요일만큼
                let nowColumn = nowRow.insertCell();        // 열 추가
            }

            for (let nowDay = firstDate; nowDay <= lastDate; nowDay.setDate(nowDay.getDate() + 1)) {   // day는 날짜를 저장하는 변수, 이번달 마지막날까지 증가시키며 반복  

                let nowColumn = nowRow.insertCell();        // 새 열을 추가하고


                let newDIV = document.createElement("p");
                newDIV.innerHTML = leftPad(nowDay.getDate());        // 추가한 열에 날짜 입력
                nowColumn.appendChild(newDIV);

                if (nowDay.getDay() == 6) {                 // 토요일인 경우
                    nowRow = tbody_Calendar.insertRow();    // 새로운 행 추가
                }

                if (nowDay < today) {                       // 지난날인 경우
                    newDIV.className = "pastDay";
                }
                else if (nowDay.getFullYear() == today.getFullYear() && nowDay.getMonth() == today.getMonth() && nowDay.getDate() == today.getDate()) { // 오늘인 경우           
                    newDIV.className = "today";
                    newDIV.onclick = function () { choiceDate(this); }
                }
                else {                                      // 미래인 경우
                    newDIV.className = "futureDay";
                    newDIV.onclick = function () { choiceDate(this); }
                }
            }
        }

        // 날짜 선택
        function choiceDate(newDIV) {
            if (document.getElementsByClassName("choiceDay")[0]) {                              // 기존에 선택한 날짜가 있으면
                document.getElementsByClassName("choiceDay")[0].classList.remove("choiceDay");  // 해당 날짜의 "choiceDay" class 제거
            }
            newDIV.classList.add("choiceDay");           // 선택된 날짜에 "choiceDay" class 추가
        }

        // 이전달 버튼 클릭
        function prevCalendar() {
            nowMonth = new Date(nowMonth.getFullYear(), nowMonth.getMonth() - 1, nowMonth.getDate());   // 현재 달을 1 감소
            buildCalendar();    // 달력 다시 생성
        }
        // 다음달 버튼 클릭
        function nextCalendar() {
            nowMonth = new Date(nowMonth.getFullYear(), nowMonth.getMonth() + 1, nowMonth.getDate());   // 현재 달을 1 증가
            buildCalendar();    // 달력 다시 생성
        }

        // input값이 한자리 숫자인 경우 앞에 '0' 붙혀주는 함수
        function leftPad(value) {
            if (value < 10) {
                value = "0" + value;
                return value;
            }
            return value;
        }
    </script>

 

코드를 읽어보니 달력을 만드는 과정은 이랬다.

 

1. 현재 날짜를 new Date()로 불러온다.

2. 현재 날짜의 월에서 첫 날과 마지막 날을 변수에 저장한다.

3. tbody에 행을 추가하고 첫 날의 요일(숫자)만큼 열을 추가한다 (지난 달)

4. 열을 추가한 뒤 p태그를 create하고 innerHTML을 한다.

5. creat한 날짜의 요일이 토요일(6)인 경우 테이블의 행을 추가한다.

6. 현재 날짜 연산자를 이용해 비교한 후 과거와, 오늘, 미래의 날에 class를 add 해 준다.

7. 다음달, 이전 달 버튼을 클릭하면 Month가 1씩 증감하고 그 달을 기준으로 다시 달력을 불러오는 함수를 호출한다.

 

 

하나투어

 

출발일을 선택한 후 다음 날짜를 클릭하면 리턴일이 되어 값을 각각 다르게 지정하고 input하고 싶었지만 잘 되지 않아 실패를 하였다.

선택한 날중 앞 뒤를 따져 class를 붙이는 것도 쉽지 않았고, 각각 다른 날을 출발일, 리턴일로 정하는 것도 아직은 어려웠다. 그래서 어쩔 수 없이 출발일 달력과 리턴일 달력을 따로 만들었다.

 

완성을 한 후 프로젝트 기한까지 시간이 남는다면 수정해 보려고 한다.

 

 

'🔥 부트캠프-웹 개발 🔥/이젠제주투어(팀프로젝트)' 카테고리의 다른 글
  • [DAY - 52] #5 팀프로젝트(기획서 작성)
  • [DAY - 51] #4 팀프로젝트(html, css, script 취합)
  • [DAY - 43] #2 팀프로젝트 (와이어프레임)
  • [DAY - 42] #1 팀프로젝트 (주제 선정 및 파트 분배)
Yeonhub
Yeonhub
✨ https://github.com/yeonhub 📧 lsy3237@gmail.com
  • Yeonhub
    비 전공자의 Be developer
    Yeonhub
  • 전체
    오늘
    어제
    • 전체보기 (169)
      • 🔍 Tech 🔍 (19)
        • Front-End (11)
        • Back-End (4)
        • AI (1)
        • Server (1)
        • Etc (2)
      • 💡 원티드 프리온보딩 챌린지 💡 (14)
        • PRE-ONBOARDING_AI (11월) (1)
        • PRE-ONBOARDING_FE (2월) (2)
        • PRE-ONBOARDING_FE (1월) (2)
        • PRE-ONBOARDING_FE (12월) (9)
      • 🔥 부트캠프-웹 개발 🔥 (118)
        • HTML5 (7)
        • CSS3 (21)
        • JavaScript (27)
        • JavaScript_advanced (9)
        • React (24)
        • Next (1)
        • MYSql (5)
        • Node (5)
        • 오늘하날(개인프로젝트) (12)
        • 이젠제주투어(팀프로젝트) (7)
      • 💻 CS 💻 (1)
        • 알고리즘 (1)
      • ⚡ 코딩테스트 ⚡ (11)
        • JavaScript (11)
      • 📚 Books 📚 (6)
        • 클린 아키텍처 (2)
        • 인사이드 자바스크립트 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    javascript fcm
    expo 길찾기
    react native firebase analytics
    라스콘
    expo admob
    react vite
    프론트엔드 테스트코드
    python node
    Node
    react native bottom sheet
    expo node fcm
    expo fcm push
    expo map
    rn bottom sheet
    node.js fcm
    expo google map
    react native expo fcm
    expo fcm
    rn admob
    react native analytics
    node fcm
    라스콘4
    node crontab
    expo 지도
    expo deep linking
    php node
    node cron
    react native admob
    컴파운드 컴포넌트 패턴
    bottom sheet
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Yeonhub
[DAY - 47] #3 팀프로젝트(바닐라스크립트 달력)
상단으로

티스토리툴바