跳到主要内容

根据滚动位置自动更新 Bootstrap 导航或列表组组件,以指示当前在视口中处于活动状态的链接。

它是如何工作的

滚动监听切换 .active 关于锚点的类 (<a>) 元素当具有该元素时 id 被锚点引用的 href 被滚动到视图中。Scrollspy 最好与 Bootstrap 一起使用 导航组件 或者 列表组,但它也能与当前页面中的任何锚点元素一起使用。下面是它的工作原理。

  • 首先,scrollspy 需要两样东西:导航、列表组或一组简单的链接,以及一个可滚动的容器。可滚动的容器可以是 <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>

  • 不可见的目标元素将被忽略。请参阅下面的 不可见的元素 部分。

示例

向下滚动导航栏下方的区域,并观察活动类的变化。打开下拉菜单,并观察下拉菜单项也被高亮显示。

第一标题

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

第二个标题

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示的效果。

第三个标题

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

第四标题

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示的效果。

第五标题

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

<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>

嵌套导航

Scrollspy 也适用于嵌套的 .nav。如果一个嵌套的 .nav 是 .active,它的父级也将是 .active。滚动导航栏旁边的区域,并观察活动类的变化。

项目 1

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 1-1

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 1-2

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 2

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 3

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 3-1

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

项目 3-2

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

请记住,JavaScript 插件会尝试在所有可能可见的元素中选择正确的元素。多个可见的 scrollspy 目标同时出现可能会引起一些问题。

<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。滚动列表组旁边的区域,观察活动类的变化。

项目 1

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

项目 2

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

项目 3

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

第4项

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

<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 不仅限于导航组件和列表组,因此它可以在当前文档中的任何 <a> 锚点元素上工作。滚动区域并观察 .active 类的变化。

项目 1

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

项目 2

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

项目 3

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本以强调滚动和高亮显示。

第4项

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

项目5

这是滚动监视页面的一些占位内容。请注意,当你向下滚动页面时,相应的导航链接会被高亮显示。这在整个组件示例中反复出现。我们在这里继续添加一些示例文本,以强调滚动和高亮显示。

<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 类。在不可见容器中初始化的 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()
  })
})

用法

通过数据属性

要轻松地为顶栏导航添加 scrollspy 行为,请将 data-bs-spy="scroll" 添加到你想要监视的元素(最典型的是 <body>)。然后添加 data-bs-target 属性,并使用 id 或任何 Bootstrap .nav 组件父元素的类名。

<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 开始,所有组件都支持一个 实验性的保留数据属性 data-bs-config,它可以用作存放简单组件配置的 JSON 字符串。当一个元素同时拥有 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合并的结果,其中最新提供的键值会覆盖其他键值。

名称类型默认值描述
rootMarginstring0px 0px -25%Intersection Observer rootMargin 有效单位,用于计算滚动位置。
smoothScrollbooleanfalse当用户点击指向 ScrollSpy 可观察对象的链接时启用平滑滚动。
target字符串, DOM 元素null指定用于应用 Scrollspy 插件的元素。
thresholdarray[0.1, 0.5, 1]IntersectionObserver threshold 有效输入,用于计算滚动位置。

已弃用选项

直到 v5.1.3,我们一直使用 offset 和 method 选项,这些选项现在已被弃用,并被 rootMargin 取代。为了保持向后兼容性,我们将继续将给定的 offset 解析为 rootMargin,但此功能将在 v6 中移除。

方法

方法描述
dispose销毁元素的 scrollspy。(移除 DOM 元素上存储的数据)
getInstance静态方法,用于获取与 DOM 元素关联的 scrollspy 实例。
getOrCreateInstance静态方法,用于获取与 DOM 元素关联的 scrollspy 实例,或者在未初始化时创建一个新的实例。
refresh在 DOM 中添加或移除元素时,需要调用 refresh 方法。

这是一个使用刷新方法的示例:

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

事件

事件描述
activate.bs.scrollspy每当滚动监视(scrollspy)激活一个锚点时,此事件会在滚动元素上触发。
const firstScrollSpyEl = document.querySelector('[data-bs-spy="scroll"]')
firstScrollSpyEl.addEventListener('activate.bs.scrollspy', () => {
  // do something...
})