본문 바로가기
JavaScript

[Javascript] Scroll

by teamnova 2024. 5. 10.
728x90

 

오늘은 버튼을 누를시, 해당 화면으로 스크롤되는 기능을 만들어보겠습니다. 

아래 코드를 참고하셔서 동작을 확인하세요. 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Scroll</title>
    <!-- font-awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />
    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <header id="home">
      <!-- navbar -->
      <nav id="nav">
        <div class="nav-center">
          <!-- nav header -->
          <div class="nav-header">
            <img src="./logo.svg" class="logo" alt="logo" />
            <button class="nav-toggle">
              <i class="fas fa-bars"></i>
            </button>
          </div>
          <!-- links -->
          <div class="links-container">
            <ul class="links">
              <li>
                <a href="#home" class="scroll-link">home</a>
              </li>
              <li>
                <a href="#about" class="scroll-link">about</a>
              </li>
              <li>
                <a href="#services" class="scroll-link">services</a>
              </li>
              <li>
                <a href="#tours" class="scroll-link">tours</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
      <!-- banner -->
      <div class="banner">
        <div class="container">
          <h1>scroll project</h1>
          <p>
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quas eos
            neque sunt in? Id, necessitatibus quos quisquam distinctio
            laudantium fugiat?
          </p>
          <a href="#tours" class="scroll-link btn btn-white">explore tours</a>
        </div>
      </div>
    </header>
    <!-- about -->
    <section id="about" class="section">
      <div class="title">
        <h2>about <span>us</span></h2>
      </div>
    </section>
    <!-- services -->
    <section id="services" class="section">
      <div class="title">
        <h2>our <span>services</span></h2>
      </div>
    </section>
    <!-- contact -->
    <section id="tours" class="section">
      <div class="title">
        <h2>featured <span>tours</span></h2>
      </div>
    </section>
    <!-- footer -->
    <footer class="section">
      <p>
        copyright &copy; backroads travel tours company
        <span id="date"></span>. all rights reserved
      </p>
    </footer>
    <a class="scroll-link top-link" href="#home">
      <i class="fas fa-arrow-up"></i>
    </a>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

 

App.js

// ID 'date'인 span 요소를 선택하고, 현재 연도로 내부 HTML을 설정합니다.
const date = document.getElementById("date");
date.innerHTML = new Date().getFullYear();

// ********** 네비게이션 링크 표시 전환 ************
// 네비게이션 토글 버튼과 링크 컨테이너를 선택합니다.
const navToggle = document.querySelector(".nav-toggle");
const linksContainer = document.querySelector(".links-container");
const links = document.querySelector(".links");

// 토글 버튼에 클릭 이벤트 리스너를 추가합니다.
navToggle.addEventListener("click", function () {
  // 링크와 해당 컨테이너의 현재 높이를 구합니다.
  const linksHeight = links.getBoundingClientRect().height;
  const containerHeight = linksContainer.getBoundingClientRect().height;
  // 컨테이너의 높이가 0이면 링크의 높이로 설정하고, 그렇지 않으면 0으로 설정합니다.
  if (containerHeight === 0) {
    linksContainer.style.height = `${linksHeight}px`;
  } else {
    linksContainer.style.height = 0;
  }
});

// ********** 고정된 네비바 설정 ************
// 네비바와 '맨 위로' 링크를 선택합니다.
const navbar = document.getElementById("nav");
const topLink = document.querySelector(".top-link");

// 스크롤 이벤트 리스너를 윈도우에 추가합니다.
window.addEventListener("scroll", function () {
  // 현재 스크롤된 높이를 구합니다.
  const scrollHeight = window.pageYOffset;
  const navHeight = navbar.getBoundingClientRect().height;
  // 스크롤 높이가 네비바 높이보다 크면 'fixed-nav' 클래스를 추가합니다.
  if (scrollHeight > navHeight) {
    navbar.classList.add("fixed-nav");
  } else {
    navbar.classList.remove("fixed-nav");
  }

  // 스크롤 높이가 500px 이상이면 'show-link' 클래스를 추가하여 '맨 위로' 링크를 표시합니다.
  if (scrollHeight > 500) {
    topLink.classList.add("show-link");
  } else {
    topLink.classList.remove("show-link");
  }
});

// ********** 부드러운 스크롤 구현 ************
// 모든 'scroll-link' 클래스를 가진 링크들을 선택합니다.
const scrollLinks = document.querySelectorAll(".scroll-link");
scrollLinks.forEach((link) => {
  // 링크 클릭 시 기본 동작을 방지합니다.
  link.addEventListener("click", (e) => {
    e.preventDefault();
    // 클릭된 링크의 href에서 ID를 추출하여 해당 위치로 스크롤합니다.
    const id = e.currentTarget.getAttribute("href").slice(1);
    const element = document.getElementById(id);

    // 네비바와 링크 컨테이너의 높이를 구하고, 네비바가 고정되어 있는지 확인합니다.
    const navHeight = navbar.getBoundingClientRect().height;
    const containerHeight = linksContainer.getBoundingClientRect().height;
    const fixedNav = navbar.classList.contains("fixed-nav");
    let position = element.offsetTop - navHeight;

    // 네비바가 고정되어 있지 않으면 위치를 조정합니다.
    if (!fixedNav) {
      position = position - navHeight;
    }
    // 네비바의 높이가 82px보다 크면 컨테이너 높이를 더해줍니다.
    if (navHeight > 82) {
      position = position + containerHeight;
    }

    // 계산된 위치로 페이지를 스크롤합니다.
    window.scrollTo({
      left: 0,
      top: position,
    });
    // 링크 컨테이너의 높이를 0으로 설정하여 닫습니다.
    linksContainer.style.height = 0;
  });
});

'JavaScript' 카테고리의 다른 글

[Javascript] count-down timer  (0) 2024.05.26
[Javascript] tabs  (0) 2024.05.20
[Javascript] 식당 메뉴판 만들기  (0) 2024.05.04
[Javascript] 버튼 이동 시키기  (0) 2024.04.29
[Javascript] FAQ 페이지 만들기  (2) 2024.04.28