Front-End/JavaScript

JavaScript - 달력 구현 [버튼기능 최적화]

hyeeoooook 2026. 1. 11. 23:28

버튼이 클릭될때 년도와 월을 선택할 수 있는 div태그가 아래로 열리는 로직

function calendarSelector_Year() {
  const yearBtn = document.getElementById("calendar_Year");
  const yearSelector = document.getElementById("calendar_Year_choice");
  yearBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    if (yearSelector.classList.contains("h-30")) {
      yearSelector.classList.remove("h-30");
      yearSelector.classList.add("h-0");
      yearSelector.classList.add("opacity-0");
    } else {
      yearSelector.classList.remove("h-0");
      yearSelector.classList.add("h-30");
      yearSelector.classList.remove("opacity-0");
    }
  });

  yearSelector.addEventListener("click", (e) => {
    e.stopPropagation();
  });

  document.addEventListener("click", (e) => {
    if (!yearSelector.classList.contains("h-0")) {
      yearSelector.classList.remove("h-30");
      yearSelector.classList.add("h-0");
      yearSelector.classList.add("opacity-0");
    }
  });
}

calendarSelector_Year();
calendarSelector_Month();

function calendarSelector_Month() {
  const calendar_Month = document.getElementById("calendar_Month_choice");
  const calendar_Month_button = document.getElementById("calendar_Month");

  calendar_Month_button.addEventListener("click", (e) => {
    e.stopPropagation();
    if (calendar_Month.classList.contains("h-30")) {
      calendar_Month.classList.remove("h-30");
      calendar_Month.classList.add("h-0");
      calendar_Month.classList.add("opacity-0");
    } else {
      calendar_Month.classList.remove("h-0");
      calendar_Month.classList.add("h-30");
      calendar_Month.classList.remove("opacity-0");
    }
  });

  calendar_Month.addEventListener("click", (e) => {
    e.stopPropagation();
  });

  document.addEventListener("click", () => {
    if (!calendar_Month.classList.contains("h-0")) {
      calendar_Month.classList.remove("h-30");
      calendar_Month.classList.add("h-0");
      calendar_Month.classList.add("opacity-0");
    }
  });
}

 

year 버튼과 month 버튼의 이벤트를 따로 관리하다가 이보다는 성능적으로도 사용자의 입장에서도 더 나은 방안을 생각해 보았을때, 두개의 버튼을 함께 관리하지만 각각의 버튼이 눌릴때 그에 해당하는 객체값을 출력하는 로직의 필요성을 느낌.

 


calendarButtonControler 함수 구현

function calendarButtonControler() {
  const calendar_YearMonth_choice = document.getElementById(
    "calendar_YearMonth_choice"
  );
  const monthBtn = document.getElementById("calendar_Month");
  const yearBtn = document.getElementById("calendar_Year");

  const calendar_YearMonth_contents = document.getElementById("calendar_YearMonth_contents");

  let currentMode = null;

  function calendarButtonClick(e) {
    e.stopPropagation();

    const clickMode = e.currentTarget === yearBtn ? "year" : "month";

    if (currentMode === clickMode) {
      if (calendar_YearMonth_choice.classList.contains("h-30")) {
        calendar_YearMonth_choice.classList.remove("h-30", "opacity-100");
        calendar_YearMonth_choice.classList.add("h-0");
      }

      currentMode = null;
      return;
    }

    if (calendar_YearMonth_choice.classList.contains("h-0")) {
      calendar_YearMonth_choice.classList.remove("h-0");
      calendar_YearMonth_choice.classList.add("h-30", "opacity-100");
    }

    if (e.currentTarget === yearBtn) {
      currentMode = "year";
      calendar_YearMonth_contents.textContent ="년도";
    } else if (e.currentTarget === monthBtn) {
      currentMode = "month";
      calendar_YearMonth_contents.textContent = "월";
    }
  }
  document.addEventListener("click", () => {
    if (!calendar_YearMonth_choice.classList.contains("h-0")) {
      calendar_YearMonth_choice.classList.remove("h-30", "opacity-100");
      calendar_YearMonth_choice.classList.add("h-0");
    }
    currentMode = null;
  });
  calendar_YearMonth_choice.addEventListener("click", (e) => {
    e.stopPropagation();
  });
  yearBtn.addEventListener("click", calendarButtonClick);
  monthBtn.addEventListener("click", calendarButtonClick);
}
calendarButtonControler();

 

+ 년도 또는 월 버튼을 눌렀을때 내부의 text가 바뀌도록 구현

 

currentMode라는 변수와 clickMode를 추가해서 현재의 모드와 클릭되는 모드가 각각 같을경우 창이 닫히도록 구현(달력 객체를 제외한 다른 부분을 눌러도 창이 닫힘)

 

앞으로 해야할 것

 - 버튼을 눌렀을때, year일경우 년도가 출력되고 month일 경우에 월을 contents 안에 배치한다.

 - content 내부에 있는 월 또는 년도를 눌렀을 경우 해당 년도 또는 월로 달력이 이동한다.

 - 구현한 자바스크립트 로직이 현재 완성도가 떨어짐. 함수화 시켜서 필요한 내용들을 재사용 할 수 있도록 리팩토링 작업이 필수