반응형

웹사이트의 상단 메뉴는 사용자의 탐색을 돕는 중요한 요소입니다. 하지만 화면 공간을 최대한 활용하려면 상단 메뉴를 동적으로 제어하는 기능이 필요할 수 있습니다. 이번 블로그에서는 스크롤 방향에 따라 상단 메뉴가 나타나거나 사라지게 하는 예제를 구현하는 방법을 소개합니다.


1. 구현 목표

  • 사용자가 스크롤을 아래로 내릴 때: 상단 메뉴가 화면에서 사라짐.
  • 사용자가 스크롤을 위로 올릴 때: 상단 메뉴가 다시 나타남.
  • 사용자가 페이지 상단에 있을 경우: 상단 메뉴가 항상 표시됨.

2. 활용 사례

  1. 콘텐츠 중심의 웹사이트:
    • 화면 공간을 절약해 콘텐츠를 강조하고자 할 때.
  2. 모바일 웹사이트:
    • 작은 화면에서 유용한 인터페이스 제공.
  3. 블로그, 뉴스 사이트:
    • 사용자가 내용을 읽는 동안 방해를 최소화.

3. 구현 방법 개요

  1. HTML: 상단 메뉴와 기본 페이지 레이아웃 구성.
  2. CSS: 상단 메뉴의 스타일 지정 및 애니메이션 효과 추가.
  3. JavaScript: 스크롤 이벤트를 감지하고 방향에 따라 메뉴 표시 상태를 제어.

4. HTML 구조 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>스크롤 동적 상단 메뉴</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header id="topMenu">
        <nav>
            <ul>
                <li><a href="#">Home</a></li>
                <li><a href="#">About</a></li>
                <li><a href="#">Services</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <section>
            <h1>스크롤 테스트</h1>
            <p>여기에 페이지 내용을 작성하세요. 아래로 스크롤하면 상단 메뉴가 사라지고, 위로 스크롤하면 다시 나타납니다.</p>
        </section>
        <section style="height: 2000px;">
            <p>스크롤 테스트를 위한 긴 페이지입니다.</p>
        </section>
    </main>
    <script src="script.js"></script>
</body>
</html>

설명:

  • header#topMenu: 상단 메뉴를 감싸는 요소.
  • main: 스크롤 테스트를 위한 긴 콘텐츠.

5. CSS 스타일링

/* styles.css */

/* 초기 설정 */
body {
    margin: 0;
    font-family: Arial, sans-serif;
    line-height: 1.6;
}

header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #333;
    color: white;
    z-index: 1000;
    padding: 10px 20px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
    transition: transform 0.3s ease-in-out;
}

header nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: space-around;
}

header nav ul li {
    display: inline;
}

header nav ul li a {
    text-decoration: none;
    color: white;
    padding: 10px 15px;
    transition: background-color 0.3s;
}

header nav ul li a:hover {
    background-color: #575757;
}

/* 숨김 효과 */
header.hidden {
    transform: translateY(-100%);
}

/* 메인 콘텐츠 */
main {
    padding-top: 70px; /* 고정된 헤더 아래에 공간 확보 */
}

section {
    padding: 20px;
    text-align: center;
}

설명:

  • header.hidden: 스크롤 시 상단 메뉴가 위로 사라지는 애니메이션 적용.
  • transition: transform 속성에 애니메이션 효과 추가.

6. JavaScript 작성

6.1 기본 스크립트

// script.js

let lastScrollY = 0; // 마지막 스크롤 위치
const topMenu = document.getElementById('topMenu'); // 상단 메뉴

// 스크롤 이벤트 처리
window.addEventListener('scroll', () => {
    const currentScrollY = window.scrollY;

    if (currentScrollY > lastScrollY) {
        // 스크롤을 아래로 내릴 때
        topMenu.classList.add('hidden');
    } else {
        // 스크롤을 위로 올릴 때
        topMenu.classList.remove('hidden');
    }

    lastScrollY = currentScrollY;
});

설명:

  • lastScrollY: 이전 스크롤 위치를 저장해 현재 위치와 비교.
  • window.scrollY: 현재 스크롤 위치를 가져옴.
  • classList.addclassList.remove: 조건에 따라 hidden 클래스 추가/제거.

6.2 최적화: 디바운스 적용

스크롤 이벤트는 매우 빈번하게 발생하므로 성능을 최적화하기 위해 디바운스(debounce)를 사용합니다.

let lastScrollY = 0;
const topMenu = document.getElementById('topMenu');
let timer = null;

window.addEventListener('scroll', () => {
    if (timer !== null) {
        clearTimeout(timer);
    }

    timer = setTimeout(() => {
        const currentScrollY = window.scrollY;

        if (currentScrollY > lastScrollY) {
            topMenu.classList.add('hidden');
        } else {
            topMenu.classList.remove('hidden');
        }

        lastScrollY = currentScrollY;
    }, 100); // 100ms마다 처리
});

설명:

  • 디바운스를 적용해 스크롤 이벤트 호출 횟수를 줄임.

7. 추가 기능: 페이지 상단에서는 항상 메뉴 표시

페이지 최상단에서는 메뉴가 항상 표시되도록 조건을 추가합니다.

window.addEventListener('scroll', () => {
    const currentScrollY = window.scrollY;

    if (currentScrollY === 0) {
        topMenu.classList.remove('hidden');
    } else if (currentScrollY > lastScrollY) {
        topMenu.classList.add('hidden');
    } else {
        topMenu.classList.remove('hidden');
    }

    lastScrollY = currentScrollY;
});

설명:

  • currentScrollY === 0: 스크롤 위치가 최상단인지 확인.

8. 결과

위 코드를 실행하면 다음과 같은 기능을 구현할 수 있습니다:

  1. 사용자가 스크롤을 아래로 내리면 상단 메뉴가 부드럽게 사라짐.
  2. 스크롤을 위로 올리면 상단 메뉴가 다시 나타남.
  3. 페이지 최상단에서는 항상 상단 메뉴가 표시됨.

9. 확장 가능성

  1. 애니메이션 효과 변경:
    • CSS의 transition 속성을 활용해 더 다양한 애니메이션 효과를 적용할 수 있습니다.
  2. 모바일 환경 최적화:
    • 모바일 디바이스에서 터치 스크롤 이벤트를 추가로 처리할 수 있습니다.
  3. 상단 메뉴에 투명도 적용:
    • 스크롤에 따라 메뉴의 배경색을 변경하거나 투명도를 조정할 수 있습니다.

10. 마무리

이번 글에서는 JavaScript와 CSS를 사용해 스크롤 방향에 따라 상단 메뉴가 동적으로 나타나거나 사라지게 하는 방법을 구현해 보았습니다. 이를 활용하면 사용자 경험을 향상시키고, 화면 공간을 효율적으로 활용할 수 있습니다. 직접 구현해보고 여러분의 프로젝트에 적용해 보세요!

반응형

+ Recent posts