탭클릭시 스크롤앵커-2

beomhak lee·2025년 6월 11일

work_tip

목록 보기
36/37
post-thumbnail

탭링크를 누르거나 해당영역에 진입하면 nav가 active 클래스가 붙고 해당영역으로 부드럽게 이동하는 기능입니다.

<div class="event">
  <header>
    <div class="back">
      <img src="images/sample.jpg" alt="">
    </div>
    <nav>
      <ul>
        <li class="active"><a href="#section01">프리미엄 <br> 라운지 이벤트</a></li>
        <li><a href="#section02">럭셔리 <br> 래플</a></li>
        <li style="letter-spacing: -0.2vw;"><a href="#section03">쇼총무가 쏜다 <br> 메가커피 이벤트</a></li>
        <li><a href="#section04">오픈 한정 <br> 브랜드 팝업</a></li>
        <li><a href="#section05">오픈 한정 <br> 위클리멤톡</a></li>
      </ul>
    </nav>
  </header>
  <div class="invitation">
    <section id="section01">
      <h2>프리미엄 <br> 라운지 이벤트</h2>
      <div class="txtBox">
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi, eaque. Ad soluta eligendi natus expedita nobis qui esse nisi cupiditate recusandae ipsam odit consectetur, perferendis nihil quod aliquam officia veritatis?
      </div>
    </section>
    <section id="section02">
      <h2>럭셔리 <br> 래플</h2>
      <div class="txtBox">
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi, eaque. Ad soluta eligendi natus expedita nobis qui esse nisi cupiditate recusandae ipsam odit consectetur, perferendis nihil quod aliquam officia veritatis?
      </div>
    </section>
    <section id="section03">
      <h2>쇼총무가 쏜다 <br> 메가커피 이벤트</h2>
      <div class="txtBox">
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi, eaque. Ad soluta eligendi natus expedita nobis qui esse nisi cupiditate recusandae ipsam odit consectetur, perferendis nihil quod aliquam officia veritatis?
      </div>
    </section>
    <section id="section04">
      <h2>오픈 한정 <br> 브랜드 팝업</h2>
      <div class="txtBox">
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi, eaque. Ad soluta eligendi natus expedita nobis qui esse nisi cupiditate recusandae ipsam odit consectetur, perferendis nihil quod aliquam officia veritatis?
      </div>
    </section>
    <section id="section05">
      <h2>오픈 한정 <br> 위클리멤톡</h2>
      <div class="txtBox">
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi, eaque. Ad soluta eligendi natus expedita nobis qui esse nisi cupiditate recusandae ipsam odit consectetur, perferendis nihil quod aliquam officia veritatis?
      </div>
    </section>
  </div>
  </div>
*{margin:0; padding:0; text-decoration: none; list-style: none;}
.event {padding:0 30px}
.event header {text-align: center; position:fixed; width: 100%; left:0; top:0;}
.event header img {width: 100%; display: block;}
.event h2 {padding-block: 30px;}
.event h3 {margin-bottom: 10px;}
.event p {padding-bottom: 20px;}
.event nav ul {display: flex; justify-content: center; font-size: 2.0313vw;}
.event nav ul li{ width: 25%;}
.event nav ul li.active a {color:red}
.event nav ul li a {color:#fff; display: block; background-color: rgb(72, 115, 115); padding:1.5625vw}
.event section .txtBox {border:1px solid red; height: 1000px;}
$(document).ready(function () {
  // header 영역 높이값 구하기
  let headerHeight = $('header').outerHeight();

  function updateHeaderHeight() {
    headerHeight = $('header').outerHeight();
    // header 영역 높이만큼 invitation 에 margintop 적용
    $('.invitation').css({ 'marginTop': headerHeight });
  }

  updateHeaderHeight();
  // 화면사이즈 달라질때 header 높이값 다시 구해서 적용
  $(window).resize(updateHeaderHeight);

  $('nav a').click(function (e) {
    // 네비영역 링크 클릭시 해당 네비에 맞는 컨텐츠 영역으로 이동
    e.preventDefault();
    const targetId = $(this).attr('href');
    const $target = $(targetId);

    $('html, body').animate({
      // 고정된 헤더만큼 위로 여유를 둬서 내용이 가려지지 않게 한다.
      scrollTop: $target.offset().top - headerHeight
    }, 500);
  });

  // 현재 위치에 따른 nav 활성화 처리
  $(window).on('scroll', function () {
    const scrollPos = $(document).scrollTop();

    $('section').each(function () {
      // 현재 섹션의 문서 전체 기준 top 좌표를 가져와서 고정된 헤더 높이를 빼서, 실제로 보여지는 위치 기준으로 보정
      const top = $(this).offset().top - headerHeight - 10;
      // 이 섹션의 아래쪽 끝 위치(top + 높이)를 계산 현재 섹션이 화면에 보이는 범위(top ~ bottom)를 정합니다.
      const bottom = top + $(this).outerHeight();
      // 이 섹션의 id 속성 값을 가져옵니다.
      const id = $(this).attr('id');

      // 현재 스크롤 위치(scrollPos)가 이 섹션의 범위 안에 있는지를 판단
      if (scrollPos >= top && scrollPos < bottom) {
        $('nav li').removeClass('active');
        // 현재 보고 있는 섹션(id)에 해당하는 <a> 태그를 찾고
        // 그 부모 <li> 요소에 active 클래스를 추가
        $(`nav a[href="#${id}"]`).parent().addClass('active');
      }
    });
  });
});

0개의 댓글