スクロールスパイ Scrollspy
スクロール位置に基づいて Bootstrap のナビゲーションやリストグループコンポーネントを自動的に更新し、ビューポート内でどのリンクが現在アクティブであるかを示します。
動作の仕組み
Scrollspy は、アンカーの href によって参照される id を持つ要素がスクロールしてビューに入ったときに、アンカー(<a>)要素の .active クラスを切り替えます。Scrollspy は Bootstrap の nav コンポーネントまたはリストグループと組み合わせて使用するのが最適ですが、現在のページ内の任意のアンカー要素でも機能します。以下は動作の仕組みです。
-
始めるには、scrollspy には2つのものが必要です:ナビゲーション、リストグループ、または単純なリンクのセットと、スクロール可能なコンテナです。スクロール可能なコンテナは
<body>か、設定されたheightとoverflow-y: scrollを持つカスタム要素です。 -
スクロール可能なコンテナに、
data-bs-spy="scroll"とdata-bs-target="#navId"を追加します。ここでnavIdは関連するナビゲーションの一意のidです。要素内にフォーカス可能な要素がない場合は、キーボードアクセスを確保するためにtabindex="0"も含めるようにしてください。 -
「監視対象」のコンテナをスクロールすると、関連するナビゲーション内のアンカーリンクから
.activeクラスが追加および削除されます。リンクには解決可能なidターゲットが必要です。そうでない場合は無視されます。例えば、<a href="#home">home</a>は DOM 内の<div id="home"></div>のようなものに対応している必要があります。 -
表示されていないターゲット要素は無視されます。以下の非表示要素セクションを参照してください。
例
Navbar
navbar の下のエリアをスクロールして、アクティブクラスの変更を確認してください。ドロップダウンメニューを開くと、ドロップダウンアイテムも強調表示されます。
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
Scrollspy はネストされた .nav でも動作します。ネストされた .nav が .active の場合、その親も .active になります。navbar の横のエリアをスクロールして、アクティブクラスの変更を確認してください。
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>
リストグループ
Scrollspy は .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>
シンプルなアンカー
Scrollspy は nav コンポーネントやリストグループに限定されないため、現在のドキュメント内の任意の <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>
非表示要素
表示されていないターゲット要素は無視され、対応する nav アイテムは .active クラスを受け取りません。非表示のラッパーで初期化された scrollspy インスタンスは、すべてのターゲット要素を無視します。ラッパーが表示されるようになったら、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()
})
})
使い方
data 属性経由
トップバーナビゲーションに scrollspy の動作を簡単に追加するには、監視する要素(最も一般的には <body>)に data-bs-spy="scroll" を追加します。次に、Bootstrap の .nav コンポーネントの親要素の id またはクラス名を持つ data-bs-target 属性を追加します。
<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'
})
オプション
オプションはdata属性またはJavaScriptを介して渡すことができます。data-bs-にオプション名を追加できます。例: data-bs-animation="{value}"。data属性を介してオプションを渡す場合は、オプション名の大文字小文字を"camelCase"から"kebab-case"に変更してください。例えば、data-bs-customClass="beautifier"の代わりにdata-bs-custom-class="beautifier"を使用します。
Bootstrap 5.2.0以降、すべてのコンポーネントは、JSON文字列として単純なコンポーネント設定を格納できる実験的な予約済みdata属性data-bs-configをサポートしています。要素にdata-bs-config='{"delay":0, "title":123}'とdata-bs-title="456"属性がある場合、最終的なtitle値は456になり、個別のdata属性はdata-bs-configで指定された値を上書きします。さらに、既存のdata属性はdata-bs-delay='{"show":0,"hide":150}'のようなJSON値を格納できます。
最終的な設定オブジェクトは、data-bs-config、data-bs-、およびjs objectのマージされた結果であり、最後に指定されたキー値が他の値を上書きします。
| Name | Type | Default | Description |
|---|---|---|---|
rootMargin | string | 0px 0px -25% | スクロール位置を計算する際の Intersection Observer の rootMargin 有効単位。 |
smoothScroll | boolean | false | ユーザーが ScrollSpy の監視対象を参照するリンクをクリックしたときに、スムーズスクロールを有効にします。 |
target | string, DOM element | null | Scrollspy プラグインを適用する要素を指定します。 |
threshold | array | [0.1, 0.5, 1] | スクロール位置を計算する際の IntersectionObserver の threshold 有効入力。 |
非推奨のオプション
v5.1.3 まで、offset と method オプションを使用していましたが、これらは現在非推奨となり、rootMargin に置き換えられました。
後方互換性を維持するために、指定された offset を rootMargin に解析し続けますが、この機能は v6 で削除されます。
メソッド
| Method | Description |
|---|---|
dispose | 要素の scrollspy を破棄します。(DOM 要素に保存されているデータを削除します) |
getInstance | DOM 要素に関連付けられた scrollspy インスタンスを取得する Static メソッド。 |
getOrCreateInstance | DOM 要素に関連付けられた scrollspy インスタンスを取得するか、初期化されていない場合は新しいものを作成する Static メソッド。 |
refresh | DOM で要素を追加または削除する場合は、refresh メソッドを呼び出す必要があります。 |
refresh メソッドを使用した例を以下に示します:
const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]')
dataSpyList.forEach(dataSpyEl => {
bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh()
})
イベント
| Event | Description |
|---|---|
activate.bs.scrollspy | このイベントは、scrollspy によってアンカーがアクティブ化されるたびに、スクロール要素で発生します。 |
const firstScrollSpyEl = document.querySelector('[data-bs-spy="scroll"]')
firstScrollSpyEl.addEventListener('activate.bs.scrollspy', () => {
// do something...
})