Bootstrap Scrollspy

Автоматическое обновление компонентов навигации Bootstrap или группы списков в зависимости от положения прокрутки, чтобы указать, какая ссылка в данный момент активна в области просмотра.

Как это работает

Scrollspy переключает класс .active в элементах привязки (<a>), когда элемент id, на который ссылается привязка href, прокручивается в поле зрения. Scrollspy лучше всего использовать в сочетании с загрузочным навигационным компонентом или группой списков, но он также будет работать с любыми элементами привязки на текущей странице. Вот как это работает.

  • Для запуска 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="#">Панель навигации</a>
  <ul class="nav nav-pills">
    <li class="nav-item">
      <a class="nav-link" href="#scrollspyHeading1">Первый</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#scrollspyHeading2">Второй</a>
    </li>
    <li class="nav-item dropdown">
      <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Выпадающий список</a>
      <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#scrollspyHeading3">Третий</a></li>
        <li><a class="dropdown-item" href="#scrollspyHeading4">Четвертый</a></li>
        <li><hr class="dropdown-divider"></li>
        <li><a class="dropdown-item" href="#scrollspyHeading5">Пятый</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">Первый заголовок</h4>
  <p>...</p>
  <h4 id="scrollspyHeading2">Второй заголовок</h4>
  <p>...</p>
  <h4 id="scrollspyHeading3">Третий заголовок</h4>
  <p>...</p>
  <h4 id="scrollspyHeading4">Четвертый заголовок</h4>
  <p>...</p>
  <h4 id="scrollspyHeading5">Пятый заголовок</h4>
  <p>...</p>
</div>
Живой пример:

Первый заголовок

Это некоторый контент-заполнитель для страницы scrollspy. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая ссылка для навигации. Это повторяется во всем примере компонента. Мы продолжаем добавлять сюда еще несколько примеров копирования, чтобы подчеркнуть прокрутку и выделение.

Второй заголовок

Это некоторый контент-заполнитель для страницы scrollspy. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая ссылка для навигации. Это повторяется во всем примере компонента. Мы продолжаем добавлять сюда еще несколько примеров копирования, чтобы подчеркнуть прокрутку и выделение.

Третий заголовок

Это некоторый контент-заполнитель для страницы scrollspy. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая ссылка для навигации. Это повторяется во всем примере компонента. Мы продолжаем добавлять сюда еще несколько примеров копирования, чтобы подчеркнуть прокрутку и выделение.

Четвертый заголовок

Это некоторый контент-заполнитель для страницы scrollspy. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая ссылка для навигации. Это повторяется во всем примере компонента. Мы продолжаем добавлять сюда еще несколько примеров копирования, чтобы подчеркнуть прокрутку и выделение.

Пятый заголовок

Это некоторый контент-заполнитель для страницы scrollspy. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая ссылка для навигации. Это повторяется во всем примере компонента. Мы продолжаем добавлять сюда еще несколько примеров копирования, чтобы подчеркнуть прокрутку и выделение.

Вложенная навигация

Scrollspy также работает с вложенными .navфайлами. Если вложенный .nav является .active, его родители также будут .active. Прокрутите область рядом с панелью навигации и понаблюдайте за изменением активного класса.

<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>
Живой пример:

Item 1

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 1-1

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 1-2

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 2

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 3

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 3-1

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Item 3-2

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Имейте в виду, что плагин JavaScript пытается выбрать правильный элемент среди всего, что может быть видно. Несколько видимых целей прокрутки одновременно могут вызвать некоторые проблемы.

Группа списков

Scrollspy также работает с .list-group. Прокрутите область рядом с группой списков и посмотрите, как меняется активный класс.

<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>
Живой пример:

Пункт 1

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 2

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 3

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 4

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Простые привязки

Scrollspy не ограничивается компонентами навигации и группами списков, поэтому он будет работать с любыми <a> элементами привязки в текущем документе. Прокрутите область и посмотрите, как .active меняется класс.

<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">Пункт 1</a>
      <a class="p-1 rounded" href="#simple-list-item-2">Пункт 2</a>
      <a class="p-1 rounded" href="#simple-list-item-3">Пункт 3</a>
      <a class="p-1 rounded" href="#simple-list-item-4">Пункт 4</a>
      <a class="p-1 rounded" href="#simple-list-item-5">Пункт 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">Пункт 1</h4>
      <p>...</p>
      <h4 id="simple-list-item-2">Пункт 2</h4>
      <p>...</p>
      <h4 id="simple-list-item-3">Пункт 3</h4>
      <p>...</p>
      <h4 id="simple-list-item-4">Пункт 4</h4>
      <p>...</p>
      <h4 id="simple-list-item-5">Пункт 5</h4>
      <p>...</p>
    </div>
  </div>
</div>
Живой пример:

Пункт 1

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 2

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 3

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 4

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Пункт 5

Это заполнитель для страницы прокрутки. Обратите внимание, что при прокрутке страницы вниз подсвечивается соответствующая навигационная ссылка. Это повторяется на протяжении всего примера компонента. Мы продолжаем добавлять сюда еще несколько примеров, чтобы подчеркнуть прокрутку и выделение.

Невидимые элементы

Целевые элементы, которые не видны, будут игнорироваться, а соответствующие им элементы навигации не получат .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. Кроме того, существующие атрибуты данных могут содержать значения JSON, такие как data-bs-delay='{"show":0,"hide":150}'.

Конечный объект конфигурации является объединенным результатом data-bs-config, data-bs-, и js object где последнее заданное значение ключа переопределяет остальные.

Имя Тип По умолчанию Описание
rootMargin строка 0px 0px -25% Наблюдатель пересечения rootMargin допустимые единицы измерения при вычислении положения прокрутки.
smoothScroll логическое значение false Обеспечивает плавную прокрутку, когда пользователь нажимает на ссылку, которая ссылается на наблюдаемые объекты ScrollSpy.
target строка, элемент DOM null Указывает элемент для применения плагина Scrollspy.
threshold массив [0.1, 0.5, 1] IntersectionObserver пороговое значение допустимого ввода при вычислении положения прокрутки.

Устаревшие опции

До версии 5.3 мы использовали опции offset & method, которые теперь устарели и заменены на rootMargin. Чтобы сохранить обратную совместимость, мы продолжим разбирать заданный offset to rootMargin, но эта функция будет удалена в версии 6.

Методы

Метод Описание
dispose Уничтожает scrollspy элемента. (Удаляет сохраненные данные в элементе DOM)
getInstance Статический метод для получения экземпляра scrollspy, связанного с элементом DOM.
getOrCreateInstance Статический метод для получения экземпляра scrollspy, связанного с элементом DOM, или для создания нового экземпляра, если он не был инициализирован.
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...
})