본문 바로가기
UX 개발/JS - Animation

간단한 스크롤 내비게이션 만들기 (CSS+JS)

반응형

코드 설명

  1. DOMContentLoaded 이벤트:
    • DOMContentLoaded 이벤트는 초기 HTML 문서가 완전히 로드되고 파싱되었을 때 발생하며, 스타일 시트, 이미지, 하위 프레임의 로드를 기다리지 않습니다.
    • document.addEventListener("DOMContentLoaded", ...)에 전달된 익명 함수는 DOM이 완전히 로드된 후에 내부 코드를 실행하도록 보장합니다.
  2. addClassOnScrollToSection 함수:
    • 이 함수는 특정 섹션이 보일 때 대상 요소에 클래스를 추가합니다.
    • 매개변수:
      • sectionId: 모니터링할 섹션의 ID입니다.
      • className: 대상 요소에 추가할 클래스입니다.
      • targetElementSelector: 클래스가 추가될 대상 요소의 선택자입니다.
    • 기능:
      • getElementByIdquerySelector를 사용하여 섹션과 대상 요소를 가져옵니다.
      • 섹션이나 대상 요소가 존재하지 않으면 함수는 종료됩니다.
      • checkScrollPosition 함수는 현재 스크롤 위치를 계산하고 섹션이 보이는지 여부를 결정합니다. 보이면 클래스가 대상 요소에 추가되고, 그렇지 않으면 제거됩니다.
      • 사용자가 스크롤할 때마다 checkScrollPosition을 호출하도록 스크롤 이벤트 리스너를 추가합니다.
      • 페이지가 로드될 때 올바른 상태를 설정하기 위해 checkScrollPosition을 초기 호출합니다.
  3. Sections 배열:
    • 섹션 ID의 배열(sections)이 생성됩니다.
    • forEach 메서드는 각 섹션 ID를 반복하고, 각 섹션에 대해 addClassOnScrollToSection을 호출하여 섹션 ID, 클래스 이름 및 대상 요소 선택자를 동적으로 전달합니다.
document.addEventListener("DOMContentLoaded", function () {
  function addClassOnScrollToSection(
    sectionId,
    className,
    targetElementSelector
  ) {
    const targetSection = document.getElementById(sectionId);
    const targetElement = document.querySelector(targetElementSelector);

    if (!targetSection || !targetElement) {
      return;
    }

    function checkScrollPosition() {
      const scrollPosition = window.scrollY + window.innerHeight / 2; // Middle of the viewport
      const sectionTop = targetSection.offsetTop;
      const sectionBottom = sectionTop + targetSection.offsetHeight;

      if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) {
        targetElement.classList.add(className);
      } else {
        targetElement.classList.remove(className);
      }

      console.log("scrollPosition", scrollPosition);
      console.log("sectionTop", sectionTop);
      console.log("sectionBottom", sectionBottom);
    }

    window.addEventListener("scroll", function () {
      checkScrollPosition();
    });

    checkScrollPosition();
  }

  const sections = ["s-1", "s-2", "s-3", "s-4"];
  sections.forEach(function (elem) {
    addClassOnScrollToSection(elem, "active", `a[href='#${elem}']`);
  });
});
반응형
외주/과외 문의