내용으로 건너뛰기 문서 내비게이션으로 건너뛰기
// Scrollspy

스크롤 위치에 따라 Bootstrap 내비게이션 또는 목록 그룹 컴포넌트를 자동으로 갱신하여 뷰포트 내에서 현재 어떤 링크가 활성화 된지를 나타냅니다.

작동 원리

스크롤스파이는 앵커의 href가 참조하는 id가 있는 요소가 보기로 스크롤될 때 앵커(<a>) 요소의 .active 클래스를 토글합니다. 스크롤스파이를 Bootstrap 내비게이션 컴포넌트 또는 목록 그룹과 함께 사용하는 것이 가장 좋지만 현재 페이지의 모든 앵커 요소와도 작동합니다. 작동 방식은 다음과 같습니다.

  • 스크롤스파이를 시작하려면 탐색, 목록 그룹 또는 간단한 링크 세트와 스크롤 가능한 컨테이너라는 두 가지가 필요합니다. 스크롤 가능한 컨테이너는 <body> 또는 heightoverflow-y: scroll이 설정된 사용자 정의 요소일 수 있습니다.

  • 스크롤 가능한 컨테이너에 data-bs-spy="scroll"data-bs-target="#navId"를 추가합니다. 여기서 navId는 연결된 탐색의 고유 id입니다. 요소 안에 포커스 가능한 요소가 없는 경우 키보드 액세스를 보장하기 위해 tabindex="0"도 포함해야 합니다.

  • 적용된 컨테이너를 스크롤하면 연결된 탐색 내의 앵커 링크에서 .active 클래스가 추가되고 제거됩니다. 링크에는 확인 가능한 id 타깃이 있어야 하며, 그렇지 않으면 무시됩니다. 예를 들어, <a href="#home">home</a><div id="home"></div>와 같은 DOM에 해당해야 합니다.

  • 표시되지 않는 대상 요소는 무시됩니다. 아래 보이지 않는 요소 섹션을 참조하세요.

예시

내비게이션 바

내비게이션 바 아래 영역을 스크롤하여 활성화된 클래스의 변화를 살펴보세요. 드롭다운 메뉴를 열면 드롭다운 아이템도 같이 강조 표시됩니다.

First heading

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Second heading

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Third heading

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Fourth heading

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Fifth heading

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

<nav id="navbar-example2" class="navbar bg-body-tertiary px-3 mb-3">
  <a class="navbar-brand" href="#">Navbar</a>
  <ul class="nav nav-pills">
    <li class="nav-item">
      <a class="nav-link" href="#scrollspyHeading1">First</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#scrollspyHeading2">Second</a>
    </li>
    <li class="nav-item dropdown">
      <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
      <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#scrollspyHeading3">Third</a></li>
        <li><a class="dropdown-item" href="#scrollspyHeading4">Fourth</a></li>
        <li><hr class="dropdown-divider"></li>
        <li><a class="dropdown-item" href="#scrollspyHeading5">Fifth</a></li>
      </ul>
    </li>
  </ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 rounded-2" tabindex="0">
  <h4 id="scrollspyHeading1">First heading</h4>
  <p>...</p>
  <h4 id="scrollspyHeading2">Second heading</h4>
  <p>...</p>
  <h4 id="scrollspyHeading3">Third heading</h4>
  <p>...</p>
  <h4 id="scrollspyHeading4">Fourth heading</h4>
  <p>...</p>
  <h4 id="scrollspyHeading5">Fifth heading</h4>
  <p>...</p>
</div>

중첩된 nav

스크롤 스파이는 중첩된 .nav에서도 동작합니다. 중첩 된 .nav.active인 경우, 그 부모도 .active가 됩니다. 내비게이션 바 옆 영역을 스크롤해서 활성화 된 클래스의 변화를 살펴보세요.

Item 1

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 1-1

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 1-2

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 2

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 3

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 3-1

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

Item 3-2

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.

<div class="row">
  <div class="col-4">
    <nav id="navbar-example3" class="h-100 flex-column align-items-stretch pe-4 border-end">
      <nav class="nav nav-pills flex-column">
        <a class="nav-link" href="#item-1">Item 1</a>
        <nav class="nav nav-pills flex-column">
          <a class="nav-link ms-3 my-1" href="#item-1-1">Item 1-1</a>
          <a class="nav-link ms-3 my-1" href="#item-1-2">Item 1-2</a>
        </nav>
        <a class="nav-link" href="#item-2">Item 2</a>
        <a class="nav-link" href="#item-3">Item 3</a>
        <nav class="nav nav-pills flex-column">
          <a class="nav-link ms-3 my-1" href="#item-3-1">Item 3-1</a>
          <a class="nav-link ms-3 my-1" href="#item-3-2">Item 3-2</a>
        </nav>
      </nav>
    </nav>
  </div>

  <div class="col-8">
    <div data-bs-spy="scroll" data-bs-target="#navbar-example3" data-bs-smooth-scroll="true" class="scrollspy-example-2" tabindex="0">
      <div id="item-1">
        <h4>Item 1</h4>
        <p>...</p>
      </div>
      <div id="item-1-1">
        <h5>Item 1-1</h5>
        <p>...</p>
      </div>
      <div id="item-1-2">
        <h5>Item 1-2</h5>
        <p>...</p>
      </div>
      <div id="item-2">
        <h4>Item 2</h4>
        <p>...</p>
      </div>
      <div id="item-3">
        <h4>Item 3</h4>
        <p>...</p>
      </div>
      <div id="item-3-1">
        <h5>Item 3-1</h5>
        <p>...</p>
      </div>
      <div id="item-3-2">
        <h5>Item 3-2</h5>
        <p>...</p>
      </div>
    </div>
  </div>
</div>

목록 그룹

스크롤스파이는 .list-group에서도 동작합니다. 목록 그룹 옆의 영역을 스크롤해서 활성화 된 클래스가 변화하는 것을 보겠습니다.

Item 1

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 2

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 3

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 4

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

<div class="row">
  <div class="col-4">
    <div id="list-example" class="list-group">
      <a class="list-group-item list-group-item-action" href="#list-item-1">Item 1</a>
      <a class="list-group-item list-group-item-action" href="#list-item-2">Item 2</a>
      <a class="list-group-item list-group-item-action" href="#list-item-3">Item 3</a>
      <a class="list-group-item list-group-item-action" href="#list-item-4">Item 4</a>
    </div>
  </div>
  <div class="col-8">
    <div data-bs-spy="scroll" data-bs-target="#list-example" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
      <h4 id="list-item-1">Item 1</h4>
      <p>...</p>
      <h4 id="list-item-2">Item 2</h4>
      <p>...</p>
      <h4 id="list-item-3">Item 3</h4>
      <p>...</p>
      <h4 id="list-item-4">Item 4</h4>
      <p>...</p>
    </div>
  </div>
</div>

단순 앵커

스크롤스파이는 탐색 컴포넌트와 목록 그룹에만 국한되지 않으므로 현재 문서의 모든 <a> 앵커 요소에서 작동합니다. 영역을 스크롤하여 .active 클래스가 변경되는 것을 확인하세요.

Item 1

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 2

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 3

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 4

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Item 5

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

<div class="row">
  <div class="col-4">
    <div id="simple-list-example" class="d-flex flex-column gap-2 simple-list-example-scrollspy text-center">
      <a class="p-1 rounded" href="#simple-list-item-1">Item 1</a>
      <a class="p-1 rounded" href="#simple-list-item-2">Item 2</a>
      <a class="p-1 rounded" href="#simple-list-item-3">Item 3</a>
      <a class="p-1 rounded" href="#simple-list-item-4">Item 4</a>
      <a class="p-1 rounded" href="#simple-list-item-5">Item 5</a>
    </div>
  </div>
  <div class="col-8">
    <div data-bs-spy="scroll" data-bs-target="#simple-list-example" data-bs-offset="0" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
      <h4 id="simple-list-item-1">Item 1</h4>
      <p>...</p>
      <h4 id="simple-list-item-2">Item 2</h4>
      <p>...</p>
      <h4 id="simple-list-item-3">Item 3</h4>
      <p>...</p>
      <h4 id="simple-list-item-4">Item 4</h4>
      <p>...</p>
      <h4 id="simple-list-item-5">Item 5</h4>
      <p>...</p>
    </div>
  </div>
</div>

보이지 않는 요소

표시되지 않는 대상 요소는 무시되며 해당 탐색 항목은 .active 클래스를 받지 않습니다. 보이지 않는 래퍼에서 초기화된 스크롤스파이 인스턴스는 모든 대상 요소를 무시합니다. 래퍼가 표시되면 refresh 메서드를 사용하여 관찰 가능한 요소를 확인합니다.

document.querySelectorAll('#nav-tab>[data-bs-toggle="tab"]').forEach(el => {
  el.addEventListener('shown.bs.tab', () => {
    const target = el.getAttribute('data-bs-target')
    const scrollElem = document.querySelector(`${target} [data-bs-spy="scroll"]`)
    bootstrap.ScrollSpy.getOrCreateInstance(scrollElem).refresh()
  })
})

사용 방법

데이터 속성 사용하기

topbar 내비게이션에 스크롤 스파이 동작을 간단하게 추가하려면, 스크롤 스파이 하고 싶은 요소에 data-bs-spy="scroll"를 추가합니다 (가장 전형적으로는 <body>입니다). 그 다음에 data-bs-target 속성에 임의의 Bootstrap .nav 컴포넌트의 부모 요소의 id 또는 클래스를 추가합니다.

<body data-bs-spy="scroll" data-bs-target="#navbar-example">
  ...
  <div id="navbar-example">
    <ul class="nav nav-tabs" role="tablist">
      ...
    </ul>
  </div>
  ...
</body>

JavaScript 사용하기

const scrollSpy = new bootstrap.ScrollSpy(document.body, {
  target: '#navbar-example'
})

옵션

옵션은 데이터 속성이나 JavaScript를 통해 전달할 수 있으므로 data-bs-에 옵션 이름을 추가할 수 있습니다(예: data-bs-animation="{value}"). 데이터 속성을 통해 옵션을 전달할 때 옵션 이름의 대/소문자 유형을 ‘camelCase‘에서 ‘kebab-case‘로 변경해야 합니다. 예를 들어 data-bs-custom-class="beautifier" 대신 data-bs-customClass="beautifier"를 사용합니다.

Bootstrap 5.2.0부터 모든 컴포넌트는 간단한 컴포넌트 구성을 JSON 문자열로 저장할 수 있는 experimental 예약 데이터 속성 data-bs-config를 지원합니다. 요소에 data-bs-config='{"delay":0,"title":123}'data-bs-title="456" 속성이 있는 경우 최종 title 값은 456이 되며 별도의 데이터 속성이 data-bs-config에 지정된 값을 재정의합니다. 또한 기존 데이터 속성에는 data-bs-delay='{"show":0,"hide":150}'와 같은 JSON 값을 저장할 수 있습니다.

최종 구성 개체는 data-bs-config, data-bs-, js object의 병합된 결과로, 주어진 최신 key-value가 다른 key-value를 재정의합니다.

이름 유형 기본값 설명
rootMargin string 0px 0px -25% 교차점 관찰자 rootMargin의 스크롤 위치를 계산할 때 유효한 단위입니다.
smoothScroll boolean false 사용자가 스크롤스파이 옵저버를 참조하는 링크를 클릭할 때 부드럽게 스크롤할 수 있도록 합니다.
target string, DOM element null 스크롤스파이 플러그인을 적용할 요소를 지정합니다.
threshold array [0.1, 0.5, 1] IntersectionObserver threshold의 스크롤 위치를 계산할 때 유효한 단위입니다.

지원 중단

v5.1.3까지는 offsetmethod 옵션을 사용했지만, 이제 더 이상 사용되지 않고 rootMargin으로 대체되었습니다. 이전 버전과의 호환성을 유지하기 위해 주어진 offsetrootMargin으로 계속 파싱하지만, 이 기능은 v6에서 제거될 예정입니다.

메소드

메소드 설명
dispose 요소의 스크롤스파이를 제거합니다. (DOM 요소에 저장된 데이터 제거)
getInstance 정적 메서드를 사용하여 DOM 요소와 연관된 스크롤스파이 인스턴스를 가져옵니다.
getOrCreateInstance 정적 메서드를 사용하여 DOM 요소와 연결된 스크롤스파이 인스턴스를 가져오거나 초기화되지 않은 경우 새 인스턴스를 생성할 수 있습니다.
refresh DOM에서 요소를 추가하거나 제거할 때는 새로고침 메서드를 호출해야 합니다.

다음은 refresh 메소드를 사용한 예제입니다:

const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]')
dataSpyList.forEach(dataSpyEl => {
  bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh()
})

이벤트

이벤트 설명
activate.bs.scrollspy 이 이벤트는 스크롤스파이에 의해 앵커가 활성화될 때마다 스크롤 요소에서 발생합니다.
const firstScrollSpyEl = document.querySelector('[data-bs-spy="scroll"]')
firstScrollSpyEl.addEventListener('activate.bs.scrollspy', () => {
  // do something...
})